[clang] caa1ebd - Don't assume that a new cleanup was added to InnermostEHScope.

James Y Knight via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 4 20:40:48 PST 2022


Author: James Y Knight
Date: 2022-02-04T23:39:42-05:00
New Revision: caa1ebde70673ddb7124a0599ba846362a1f8b1e

URL: https://github.com/llvm/llvm-project/commit/caa1ebde70673ddb7124a0599ba846362a1f8b1e
DIFF: https://github.com/llvm/llvm-project/commit/caa1ebde70673ddb7124a0599ba846362a1f8b1e.diff

LOG: Don't assume that a new cleanup was added to InnermostEHScope.

After fa87fa97fb79, this was no longer guaranteed to be the cleanup
just added by this code, if IsEHCleanup got disabled. Instead, use
stable_begin(), which _is_ guaranteed to be the cleanup just added.

This caused a crash when a object that is callee destroyed (e.g. with the MS ABI) was passed in a call from a noexcept function.

Added a test to verify.

Fixes: fa87fa97fb79

Added: 
    

Modified: 
    clang/lib/CodeGen/CGCall.cpp
    clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index a37ff8844e885..67a3f73525e35 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -4331,7 +4331,7 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
                                               type);
       // This unreachable is a temporary marker which will be removed later.
       llvm::Instruction *IsActive = Builder.CreateUnreachable();
-      args.addArgCleanupDeactivation(EHStack.getInnermostEHScope(), IsActive);
+      args.addArgCleanupDeactivation(EHStack.stable_begin(), IsActive);
     }
     return;
   }

diff  --git a/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp b/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
index 92fa17b145001..e6d602464d9b3 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
@@ -32,6 +32,28 @@ void HasEHCleanup() {
 // WIN32-NOT: @"??1A@@QAE at XZ"
 // WIN32: }
 
+
+// This test verifies the fix for a crash that occurred after
+// fa87fa97fb79.
+void HasEHCleanupNoexcept() noexcept {
+  TakesTwo(getA(), getA());
+}
+
+// With exceptions, we need to clean up at least one of these temporaries.
+// WIN32-LABEL: define dso_local void @"?HasEHCleanupNoexcept@@YAXXZ"() {{.*}} {
+// WIN32:   %[[base:.*]] = call i8* @llvm.stacksave()
+// WIN32:   invoke void @"?getA@@YA?AUA@@XZ"(%struct.A* sret(%struct.A) align 4 %{{.*}})
+// WIN32:   invoke void @"?getA@@YA?AUA@@XZ"(%struct.A* sret(%struct.A) align 4 %{{.*}})
+// WIN32:   invoke noundef i32 @"?TakesTwo@@YAHUA@@0 at Z"
+// WIN32:   call void @llvm.stackrestore
+// WIN32:   ret void
+//
+//    Since all the calls terminate, there should be no dtors on the unwind
+// WIN32:   cleanuppad
+// WIN32-NOT: @"??1A@@QAE at XZ"
+// WIN32: }
+
+
 void TakeRef(const A &a);
 int HasDeactivatedCleanups() {
   return TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A()));


        


More information about the cfe-commits mailing list