forked from OSchip/llvm-project
[CodeGen] Do not push a destructor cleanup for a struct that doesn't
have a non-trivial destructor. This fixes a bug introduced in r328731 where CodeGen emits calls to synthesized destructors for non-trivial C structs in C++ mode when the struct passed to EmitCallArg doesn't have a non-trivial destructor. Under Microsoft's ABI, ASTContext::isParamDestroyedInCallee currently always returns true, so it's necessary to check whether the struct has a non-trivial destructor before pushing a cleanup in EmitCallArg. This fixes PR37146. llvm-svn: 330304
This commit is contained in:
parent
54a33d7a27
commit
4ce0e5a892
|
@ -3541,13 +3541,20 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
|
|||
else
|
||||
Slot = CreateAggTemp(type, "agg.tmp");
|
||||
|
||||
Slot.setExternallyDestructed();
|
||||
bool DestroyedInCallee = true, NeedsEHCleanup = true;
|
||||
if (const auto *RD = type->getAsCXXRecordDecl())
|
||||
DestroyedInCallee = RD->hasNonTrivialDestructor();
|
||||
else
|
||||
NeedsEHCleanup = needsEHCleanup(type.isDestructedType());
|
||||
|
||||
if (DestroyedInCallee)
|
||||
Slot.setExternallyDestructed();
|
||||
|
||||
EmitAggExpr(E, Slot);
|
||||
RValue RV = Slot.asRValue();
|
||||
args.add(RV, type);
|
||||
|
||||
if (type->getAsCXXRecordDecl() || needsEHCleanup(type.isDestructedType())) {
|
||||
if (DestroyedInCallee && NeedsEHCleanup) {
|
||||
// Create a no-op GEP between the placeholder and the cleanup so we can
|
||||
// RAUW it successfully. It also serves as a marker of the first
|
||||
// instruction where the cleanup is active.
|
||||
|
|
|
@ -313,3 +313,27 @@ class_0::class_0() {
|
|||
// WIN32: br label %[[SKIP_VBASE]]
|
||||
// WIN32: [[SKIP_VBASE]]
|
||||
}
|
||||
|
||||
namespace PR37146 {
|
||||
// Check that IRGen doesn't emit calls to synthesized destructors for
|
||||
// non-trival C structs.
|
||||
|
||||
// WIN32: define dso_local void @"?test@PR37146@@YAXXZ"()
|
||||
// WIN32: call void @llvm.memset.p0i8.i32(
|
||||
// WIN32: call i32 @"?getS@PR37146@@YA?AUS@1@XZ"(
|
||||
// WIN32: call void @"?func@PR37146@@YAXUS@1@0@Z"(
|
||||
// WIN32-NEXT: ret void
|
||||
// WIN32-NEXT: {{^}$}}
|
||||
|
||||
struct S {
|
||||
int f;
|
||||
};
|
||||
|
||||
void func(S, S);
|
||||
S getS();
|
||||
|
||||
void test() {
|
||||
func(getS(), S());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue