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
This commit is contained in:
Tyler Yankee
2025-08-13 15:22:28 -04:00
parent 5d2e715182
commit 37e27f71bc
4 changed files with 10 additions and 0 deletions

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -0,0 +1 @@
0

View File

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