From e4d0faf011db11a33590755ca70c51642d64ba5b Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Fri, 27 Sep 2019 05:36:16 +0000 Subject: [PATCH] Fix use-after-free found in Clang's testsuite. We need to discard all remaining cleanups if an earlier cleanup failed, otherwise we may try to rerun the remaining cleanups later, potentially after the scope containing the object is destroyed. (This can happen when checking a potential constant expression.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@373042 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ExprConstant.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index a2a6168ddb..12dc054b81 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -1239,11 +1239,14 @@ namespace { // Run all cleanups for a block scope, and non-lifetime-extended cleanups // for a full-expression scope. + bool Success = true; for (unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) { if (!(IsFullExpression && Info.CleanupStack[I - 1].isLifetimeExtended())) { - if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) - return false; + if (!Info.CleanupStack[I - 1].endLifetime(Info, RunDestructors)) { + Success = false; + break; + } } } @@ -1254,7 +1257,7 @@ namespace { std::remove_if(NewEnd, Info.CleanupStack.end(), [](Cleanup &C) { return !C.isLifetimeExtended(); }); Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end()); - return true; + return Success; } }; typedef ScopeRAII BlockScopeRAII; -- 2.40.0