Bläddra i källkod

foreach: Explicitly skip replay without iterations

As written, foreach loops with a trailing `IN` (i.e., no loop
variable(s) given) lead to an assertion error. Handle this case by
exiting early when we know the loop won't execute anything.

Fixes: #27135
Tyler Yankee 2 månader sedan
förälder
incheckning
37e27f71bc

+ 3 - 0
Source/cmForEachCommand.cxx

@@ -100,6 +100,9 @@ bool cmForEachFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
 bool cmForEachFunctionBlocker::Replay(
   std::vector<cmListFileFunction> functions, cmExecutionStatus& inStatus)
 {
+  if (this->Args.size() == this->IterationVarsCount) {
+    return true;
+  }
   return this->ZipLists ? this->ReplayZipLists(functions, inStatus)
                         : this->ReplayItems(functions, inStatus);
 }

+ 1 - 0
Tests/RunCMake/foreach/RunCMakeTest.cmake

@@ -22,3 +22,4 @@ run_cmake(foreach-RANGE-invalid-test)
 run_cmake(foreach-RANGE-out-of-range-test)
 run_cmake(foreach-var-scope-CMP0124-OLD)
 run_cmake(foreach-var-scope-CMP0124-NEW)
+run_cmake(TrailingIn)

+ 1 - 0
Tests/RunCMake/foreach/TrailingIn-result.txt

@@ -0,0 +1 @@
+0

+ 5 - 0
Tests/RunCMake/foreach/TrailingIn.cmake

@@ -0,0 +1,5 @@
+foreach(v IN)
+endforeach()
+
+foreach(v1 v2 IN)
+endforeach()