r213976 - MS ABI: Don't push destructor cleanups for aggregate parameters in thunks

Reid Kleckner reid at kleckner.net
Fri Jul 25 14:39:46 PDT 2014


Author: rnk
Date: Fri Jul 25 16:39:46 2014
New Revision: 213976

URL: http://llvm.org/viewvc/llvm-project?rev=213976&view=rev
Log:
MS ABI: Don't push destructor cleanups for aggregate parameters in thunks

The target method of the thunk will perform the cleanup.  This can't be
tested in 32-bit x86 yet because passing something by value would create
an inalloca, and we refuse to generate broken code for that.

Added:
    cfe/trunk/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGVTables.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=213976&r1=213975&r2=213976&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Jul 25 16:39:46 2014
@@ -1656,7 +1656,9 @@ void CodeGenFunction::EmitParmDecl(const
     DeclPtr = Arg->getType() == IRTy ? Arg : Builder.CreateBitCast(Arg, IRTy,
                                                                    D.getName());
     // Push a destructor cleanup for this parameter if the ABI requires it.
-    if (!IsScalar &&
+    // Don't push a cleanup in a thunk for a method that will also emit a
+    // cleanup.
+    if (!IsScalar && !CurFuncIsThunk &&
         getTarget().getCXXABI().areArgsDestroyedLeftToRightInCallee()) {
       const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
       if (RD && RD->hasNonTrivialDestructor())

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=213976&r1=213975&r2=213976&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Fri Jul 25 16:39:46 2014
@@ -194,6 +194,7 @@ void CodeGenFunction::StartThunk(llvm::F
                                  const CGFunctionInfo &FnInfo) {
   assert(!CurGD.getDecl() && "CurGD was already set!");
   CurGD = GD;
+  CurFuncIsThunk = true;
 
   // Build FunctionArgs.
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=213976&r1=213975&r2=213976&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Jul 25 16:39:46 2014
@@ -38,16 +38,16 @@ CodeGenFunction::CodeGenFunction(CodeGen
       Builder(cgm.getModule().getContext(), llvm::ConstantFolder(),
               CGBuilderInserterTy(this)),
       CapturedStmtInfo(nullptr), SanOpts(&CGM.getLangOpts().Sanitize),
-      IsSanitizerScope(false), AutoreleaseResult(false), BlockInfo(nullptr),
-      BlockPointer(nullptr), LambdaThisCaptureField(nullptr),
-      NormalCleanupDest(nullptr), NextCleanupDestIndex(1),
-      FirstBlockInfo(nullptr), EHResumeBlock(nullptr), ExceptionSlot(nullptr),
-      EHSelectorSlot(nullptr), DebugInfo(CGM.getModuleDebugInfo()),
-      DisableDebugInfo(false), DidCallStackSave(false), IndirectBranch(nullptr),
-      PGO(cgm), SwitchInsn(nullptr), SwitchWeights(nullptr),
-      CaseRangeBlock(nullptr), UnreachableBlock(nullptr), NumReturnExprs(0),
-      NumSimpleReturnExprs(0), CXXABIThisDecl(nullptr),
-      CXXABIThisValue(nullptr), CXXThisValue(nullptr),
+      IsSanitizerScope(false), CurFuncIsThunk(false), AutoreleaseResult(false),
+      BlockInfo(nullptr), BlockPointer(nullptr),
+      LambdaThisCaptureField(nullptr), NormalCleanupDest(nullptr),
+      NextCleanupDestIndex(1), FirstBlockInfo(nullptr), EHResumeBlock(nullptr),
+      ExceptionSlot(nullptr), EHSelectorSlot(nullptr),
+      DebugInfo(CGM.getModuleDebugInfo()), DisableDebugInfo(false),
+      DidCallStackSave(false), IndirectBranch(nullptr), PGO(cgm),
+      SwitchInsn(nullptr), SwitchWeights(nullptr), CaseRangeBlock(nullptr),
+      UnreachableBlock(nullptr), NumReturnExprs(0), NumSimpleReturnExprs(0),
+      CXXABIThisDecl(nullptr), CXXABIThisValue(nullptr), CXXThisValue(nullptr),
       CXXDefaultInitExprThis(nullptr), CXXStructorImplicitParamDecl(nullptr),
       CXXStructorImplicitParamValue(nullptr), OutermostConditional(nullptr),
       CurLexicalScope(nullptr), TerminateLandingPad(nullptr),

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=213976&r1=213975&r2=213976&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Jul 25 16:39:46 2014
@@ -258,6 +258,10 @@ public:
     ~SanitizerScope();
   };
 
+  /// In C++, whether we are code generating a thunk.  This controls whether we
+  /// should emit cleanups.
+  bool CurFuncIsThunk;
+
   /// In ARC, whether we should autorelease the return value.
   bool AutoreleaseResult;
 

Added: cfe/trunk/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp?rev=213976&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp Fri Jul 25 16:39:46 2014
@@ -0,0 +1,25 @@
+// RUN: not %clang_cc1 %s -fno-rtti -triple=i686-pc-win32 -emit-llvm -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK32
+// RUN: %clang_cc1 %s -fno-rtti -triple=x86_64-pc-win32 -emit-llvm -o - | FileCheck --check-prefix=CHECK64
+
+namespace byval_thunk {
+struct Agg {
+  Agg();
+  Agg(const Agg &);
+  ~Agg();
+  int x;
+};
+
+struct A { virtual void foo(Agg x); };
+struct B { virtual void foo(Agg x); };
+struct C : A, B { virtual void foo(Agg x); };
+C c;
+
+// CHECK32: cannot compile this non-trivial argument copy for thunk yet
+
+// CHECK64-LABEL: define linkonce_odr void @"\01?foo at C@byval_thunk@@W7EAAXUAgg at 2@@Z"
+// CHECK64:             (%"struct.byval_thunk::C"* %this, %"struct.byval_thunk::Agg"* %x)
+// CHECK64:   getelementptr i8* %{{.*}}, i32 -8
+// CHECK64:   call void @"\01?foo at C@byval_thunk@@UEAAXUAgg at 2@@Z"(%"struct.byval_thunk::C"* %2, %"struct.byval_thunk::Agg"* %x)
+// CHECK64-NOT: call
+// CHECK64:   ret void
+}





More information about the cfe-commits mailing list