Эх сурвалжийг харах

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
Richard Smith 5 жил өмнө
parent
commit
e4d0faf011

+ 6 - 3
lib/AST/ExprConstant.cpp

@@ -1239,11 +1239,14 @@ namespace {
 
 
       // Run all cleanups for a block scope, and non-lifetime-extended cleanups
       // Run all cleanups for a block scope, and non-lifetime-extended cleanups
       // for a full-expression scope.
       // for a full-expression scope.
+      bool Success = true;
       for (unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
       for (unsigned I = Info.CleanupStack.size(); I > OldStackSize; --I) {
         if (!(IsFullExpression &&
         if (!(IsFullExpression &&
               Info.CleanupStack[I - 1].isLifetimeExtended())) {
               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(),
             std::remove_if(NewEnd, Info.CleanupStack.end(),
                            [](Cleanup &C) { return !C.isLifetimeExtended(); });
                            [](Cleanup &C) { return !C.isLifetimeExtended(); });
       Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
       Info.CleanupStack.erase(NewEnd, Info.CleanupStack.end());
-      return true;
+      return Success;
     }
     }
   };
   };
   typedef ScopeRAII<false> BlockScopeRAII;
   typedef ScopeRAII<false> BlockScopeRAII;