]> granicus.if.org Git - clang/commitdiff
Fix use-after-free found in Clang's testsuite.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 27 Sep 2019 05:36:16 +0000 (05:36 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 27 Sep 2019 05:36:16 +0000 (05:36 +0000)
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

index a2a6168ddbffba5d4a99b4d9b7fde0048506e524..12dc054b81ee408e24a4c3687c9b10e5bcb5e59b 100644 (file)
@@ -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<false> BlockScopeRAII;