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