From 4fcf3dd296d458562fcff5785b5b55868fed0691 Mon Sep 17 00:00:00 2001 From: Taylor Braun-Jones Date: Fri, 4 Sep 2026 13:58:51 +0000 Subject: [PATCH] CTest: Ignore a checkpoint entry for a test that is not pending CheckResume() reads the checkpoint `ctest -F` resumes from and removes each test it names. RemoveTest() erased the iterator std::find returned without checking it, so a checkpoint naming a test the current run does not have pending -- one written before the test list changed, say -- erased the end iterator of a std::list, which is undefined behavior. Skip such an entry instead. --- Source/CTest/cmCTestMultiProcessHandler.cxx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx index 731bda394b..ea51ccfea3 100644 --- a/Source/CTest/cmCTestMultiProcessHandler.cxx +++ b/Source/CTest/cmCTestMultiProcessHandler.cxx @@ -1638,8 +1638,13 @@ void cmCTestMultiProcessHandler::CheckResume() void cmCTestMultiProcessHandler::RemoveTest(int index) { - this->OrderedTests.erase( - std::find(this->OrderedTests.begin(), this->OrderedTests.end(), index)); + auto const oi = + std::find(this->OrderedTests.begin(), this->OrderedTests.end(), index); + if (oi == this->OrderedTests.end()) { + // The checkpoint names a test this run does not have pending. + return; + } + this->OrderedTests.erase(oi); this->PendingTests.erase(index); this->Properties.erase(index); this->Completed++;