r330304 - [CodeGen] Do not push a destructor cleanup for a struct that doesn't
Akira Hatanaka via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 18 16:33:15 PDT 2018
Author: ahatanak
Date: Wed Apr 18 16:33:15 2018
New Revision: 330304
URL: http://llvm.org/viewvc/llvm-project?rev=330304&view=rev
Log:
[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.
Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=330304&r1=330303&r2=330304&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Wed Apr 18 16:33:15 2018
@@ -3541,13 +3541,20 @@ void CodeGenFunction::EmitCallArg(CallAr
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.
Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp?rev=330304&r1=330303&r2=330304&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp Wed Apr 18 16:33:15 2018
@@ -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 at PR37146@@YAXXZ"()
+// WIN32: call void @llvm.memset.p0i8.i32(
+// WIN32: call i32 @"?getS at PR37146@@YA?AUS at 1@XZ"(
+// WIN32: call void @"?func at PR37146@@YAXUS at 1@0 at Z"(
+// WIN32-NEXT: ret void
+// WIN32-NEXT: {{^}$}}
+
+struct S {
+ int f;
+};
+
+void func(S, S);
+S getS();
+
+void test() {
+ func(getS(), S());
+}
+
+}
More information about the cfe-commits
mailing list