summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2014-05-11 14:04:53 (GMT)
committerStephen Kelly <steveire@gmail.com>2014-07-01 22:09:38 (GMT)
commit61ce6547424821710d0fbebf06b0eb411a630253 (patch)
tree157f3f2e3a30bdbda660a91c6c751f3dad7c1957
parentbf5fc1d5829e7995c0941996b4a515cbd46d4e4e (diff)
downloadCMake-61ce6547424821710d0fbebf06b0eb411a630253.zip
CMake-61ce6547424821710d0fbebf06b0eb411a630253.tar.gz
CMake-61ce6547424821710d0fbebf06b0eb411a630253.tar.bz2
Genex: Fix stack overflow in transitive property evaluation.
Commit v2.8.11~156^2~2 (Expand includes and defines transitively in 'external' genexes., 2013-02-13) introduced a recursive loop and a stack overflow during evaluation of a link implementation which depends on a transitive property, such as add_library(empty1 ...) add_library(empty2 ...) target_link_libraries(empty1 PRIVATE $<$<STREQUAL:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>,/foo/bar>:empty2> ) There is no use-case for code like that currently, but it should not cause a stack overflow. Avoid the recursion by reporting an error early if a case like this is found.
-rw-r--r--Source/cmGeneratorExpressionEvaluator.cxx13
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt10
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt10
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-stderr.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake10
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake14
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake10
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt1
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt8
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake14
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp7
21 files changed, 141 insertions, 0 deletions
diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx
index c925869..b648eb2 100644
--- a/Source/cmGeneratorExpressionEvaluator.cxx
+++ b/Source/cmGeneratorExpressionEvaluator.cxx
@@ -1028,6 +1028,19 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
if (dagCheckerParent->EvaluatingLinkLibraries())
{
+#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \
+ (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) ||
+ if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_COMPARE)
+ false)
+ {
+ reportError(context, content->GetOriginalExpression(),
+ "$<TARGET_PROPERTY:...> expression in link libraries "
+ "evaluation depends on target property which is transitive "
+ "over the link libraries, creating a recursion.");
+ return std::string();
+ }
+#undef TRANSITIVE_PROPERTY_COMPARE
+
if(!prop)
{
return std::string();
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt
new file mode 100644
index 0000000..7e002f5
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at LinkImplementationCycle1.cmake:5 \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:8 \(include\)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake
new file mode 100644
index 0000000..4b60214
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle1.cmake
@@ -0,0 +1,8 @@
+
+add_library(empty1 empty.cpp)
+add_library(empty2 empty.cpp)
+
+target_link_libraries(empty1
+ LINK_PUBLIC
+ $<$<STREQUAL:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt
new file mode 100644
index 0000000..2f72de6
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error at LinkImplementationCycle2.cmake:5 \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:8 \(include\)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake
new file mode 100644
index 0000000..557eac1
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle2.cmake
@@ -0,0 +1,8 @@
+
+add_library(empty1 empty.cpp)
+add_library(empty2 empty.cpp)
+
+target_link_libraries(empty1
+ LINK_PUBLIC
+ $<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-stderr.txt
new file mode 100644
index 0000000..10f3293
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3-stderr.txt
@@ -0,0 +1 @@
+^$
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake
new file mode 100644
index 0000000..0f921d4
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle3.cmake
@@ -0,0 +1,10 @@
+
+add_library(empty1 empty.cpp)
+add_library(empty2 empty.cpp)
+
+# This is OK, because evaluating the INCLUDE_DIRECTORIES is not affected by
+# the content of the INTERFACE_LINK_LIBRARIES.
+target_link_libraries(empty1
+ INTERFACE
+ $<$<STREQUAL:$<TARGET_PROPERTY:INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt
new file mode 100644
index 0000000..5cfeb0a
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake
new file mode 100644
index 0000000..ab6d0b2
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle4.cmake
@@ -0,0 +1,14 @@
+
+add_library(empty1 empty.cpp)
+add_library(empty2 empty.cpp)
+
+# The INTERFACE_INCLUDE_DIRECTORIES do not depend on the link interface.
+# On its own, this is fine. It is only when used by empty3 that an error
+# is appropriately issued.
+target_link_libraries(empty1
+ INTERFACE
+ $<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
+
+add_library(empty3 empty.cpp)
+target_link_libraries(empty3 empty1)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt
new file mode 100644
index 0000000..5cfeb0a
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake
new file mode 100644
index 0000000..dc180e3
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle5.cmake
@@ -0,0 +1,10 @@
+
+add_library(empty1 INTERFACE IMPORTED)
+add_library(empty2 INTERFACE IMPORTED)
+
+set_property(TARGET empty1 PROPERTY INTERFACE_LINK_LIBRARIES
+ $<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
+
+add_library(empty3 empty.cpp)
+target_link_libraries(empty3 empty1)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt
new file mode 100644
index 0000000..5cfeb0a
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>
+
+ \$<TARGET_PROPERTY:...> expression in link libraries evaluation depends on
+ target property which is transitive over the link libraries, creating a
+ recursion.
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake
new file mode 100644
index 0000000..91252d0
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/LinkImplementationCycle6.cmake
@@ -0,0 +1,14 @@
+
+add_library(empty1 SHARED empty.cpp)
+add_library(empty2 SHARED empty.cpp)
+
+# The INTERFACE_INCLUDE_DIRECTORIES do not depend on the link interface.
+# On its own, this is fine. It is only when used by empty3 that an error
+# is appropriately issued.
+target_link_libraries(empty1
+ INTERFACE
+ $<$<STREQUAL:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>,/foo/bar>:empty2>
+)
+
+add_library(empty3 SHARED empty.cpp)
+target_link_libraries(empty3 empty1)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake b/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
index 0ee3238..645a57d 100644
--- a/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/RunCMakeTest.cmake
@@ -15,3 +15,9 @@ run_cmake(BadInvalidName5)
run_cmake(BadInvalidName6)
run_cmake(BadInvalidName7)
run_cmake(BadInvalidName8)
+run_cmake(LinkImplementationCycle1)
+run_cmake(LinkImplementationCycle2)
+run_cmake(LinkImplementationCycle3)
+run_cmake(LinkImplementationCycle4)
+run_cmake(LinkImplementationCycle5)
+run_cmake(LinkImplementationCycle6)
diff --git a/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp b/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp
new file mode 100644
index 0000000..bfbbdde
--- /dev/null
+++ b/Tests/RunCMake/TargetPropertyGeneratorExpressions/empty.cpp
@@ -0,0 +1,7 @@
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int empty()
+{
+ return 0;
+}