aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-20 05:54:35 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-20 05:54:35 +0000
commitcb359df81b83dd4f938d05cb9cf5c34bd20068bd (patch)
treeca7dd714acdc7525b44b293bc64e47a6578863ea
parent47e8e399d25a976345a7bf07dc6c5b5fcb811740 (diff)
When creating a this-adjustment thunk where the return value is of C++
class type (that uses a return slot), pass the return slot to the callee directly rather than allocating new storage and trying to copy the object. This appears to have been the cause of the remaining two Boost.Interprocess failures. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104215 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGVTables.cpp11
-rw-r--r--test/CodeGenCXX/thunks.cpp49
2 files changed, 54 insertions, 6 deletions
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 368e2483c8..3c9b45ba8c 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -2657,8 +2657,15 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD,
CGM.getTypes().getFunctionInfo(ResultType, CallArgs,
FPT->getExtInfo());
+ // Determine whether we have a return value slot to use.
+ ReturnValueSlot Slot;
+ if (!ResultType->isVoidType() &&
+ FnInfo.getReturnInfo().getKind() == ABIArgInfo::Indirect &&
+ hasAggregateLLVMType(CurFnInfo->getReturnType()))
+ Slot = ReturnValueSlot(ReturnValue, ResultType.isVolatileQualified());
+
// Now emit our call.
- RValue RV = EmitCall(FnInfo, Callee, ReturnValueSlot(), CallArgs, MD);
+ RValue RV = EmitCall(FnInfo, Callee, Slot, CallArgs, MD);
if (!Thunk.Return.isEmpty()) {
// Emit the return adjustment.
@@ -2701,7 +2708,7 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD,
RV = RValue::get(ReturnValue);
}
- if (!ResultType->isVoidType())
+ if (!ResultType->isVoidType() && Slot.isNull())
EmitReturnOfRValue(RV, ResultType);
FinishFunction();
diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp
index 7d2edaa745..8144770763 100644
--- a/test/CodeGenCXX/thunks.cpp
+++ b/test/CodeGenCXX/thunks.cpp
@@ -86,10 +86,6 @@ void C::f() { }
}
-// This is from Test5:
-// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
-// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv(
-
// Check that the thunk gets internal linkage.
namespace {
@@ -134,4 +130,49 @@ void f(B b) {
}
}
+namespace Test6 {
+ struct X {
+ X();
+ X(const X&);
+ X &operator=(const X&);
+ ~X();
+ };
+
+ struct P {
+ P();
+ P(const P&);
+ ~P();
+ X first;
+ X second;
+ };
+
+ P getP();
+
+ struct Base1 {
+ int i;
+
+ virtual X f() { return X(); }
+ };
+
+ struct Base2 {
+ float real;
+ virtual X f() { return X(); }
+ };
+
+ struct Thunks : Base1, Base2 {
+ long l;
+
+ virtual X f();
+ };
+
+ // CHECK: define void @_ZThn16_N5Test66Thunks1fEv
+ // CHECK-NOT: memcpy
+ // CHECK: {{call void @_ZN5Test66Thunks1fEv.*sret}}
+ // CHECK: ret void
+ X Thunks::f() { return X(); }
+}
+
+// This is from Test5:
+// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
+// CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv(