forked from OSchip/llvm-project
Don't assume that a new cleanup was added to InnermostEHScope.
Afterfa87fa97fb
, 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:fa87fa97fb
This commit is contained in:
parent
dee058c670
commit
caa1ebde70
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,28 @@ void HasEHCleanup() {
|
|||
// WIN32-NOT: @"??1A@@QAE@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@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@XZ"
|
||||
// WIN32: }
|
||||
|
||||
|
||||
void TakeRef(const A &a);
|
||||
int HasDeactivatedCleanups() {
|
||||
return TakesTwo((TakeRef(A()), A()), (TakeRef(A()), A()));
|
||||
|
|
Loading…
Reference in New Issue