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@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()); +} + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits