[cfe-commits] r163866 - in /cfe/trunk: lib/CodeGen/CGVTables.cpp test/CodeGenCXX/thunks.cpp
Eli Friedman
eli.friedman at gmail.com
Thu Sep 13 18:45:09 PDT 2012
Author: efriedma
Date: Thu Sep 13 20:45:09 2012
New Revision: 163866
URL: http://llvm.org/viewvc/llvm-project?rev=163866&view=rev
Log:
Fix thunk emission for covariant virtual functions in cases which require
both a virtual and a non-virtual offset. PR13832.
Modified:
cfe/trunk/lib/CodeGen/CGVTables.cpp
cfe/trunk/test/CodeGenCXX/thunks.cpp
Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=163866&r1=163865&r2=163866&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Thu Sep 13 20:45:09 2012
@@ -79,15 +79,16 @@
static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF,
llvm::Value *Ptr,
int64_t NonVirtualAdjustment,
- int64_t VirtualAdjustment) {
+ int64_t VirtualAdjustment,
+ bool IsReturnAdjustment) {
if (!NonVirtualAdjustment && !VirtualAdjustment)
return Ptr;
llvm::Type *Int8PtrTy = CGF.Int8PtrTy;
llvm::Value *V = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy);
- if (NonVirtualAdjustment) {
- // Do the non-virtual adjustment.
+ if (NonVirtualAdjustment && !IsReturnAdjustment) {
+ // Perform the non-virtual adjustment for a base-to-derived cast.
V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment);
}
@@ -95,7 +96,7 @@
llvm::Type *PtrDiffTy =
CGF.ConvertType(CGF.getContext().getPointerDiffType());
- // Do the virtual adjustment.
+ // Perform the virtual adjustment.
llvm::Value *VTablePtrPtr =
CGF.Builder.CreateBitCast(V, Int8PtrTy->getPointerTo());
@@ -113,6 +114,11 @@
V = CGF.Builder.CreateInBoundsGEP(V, Offset);
}
+ if (NonVirtualAdjustment && IsReturnAdjustment) {
+ // Perform the non-virtual adjustment for a derived-to-base cast.
+ V = CGF.Builder.CreateConstInBoundsGEP1_64(V, NonVirtualAdjustment);
+ }
+
// Cast back to the original type.
return CGF.Builder.CreateBitCast(V, Ptr->getType());
}
@@ -199,7 +205,8 @@
ReturnValue = PerformTypeAdjustment(CGF, ReturnValue,
Thunk.Return.NonVirtual,
- Thunk.Return.VBaseOffsetOffset);
+ Thunk.Return.VBaseOffsetOffset,
+ /*IsReturnAdjustment*/true);
if (NullCheckValue) {
CGF.Builder.CreateBr(AdjustEnd);
@@ -281,7 +288,8 @@
llvm::Value *AdjustedThisPtr =
PerformTypeAdjustment(*this, ThisPtr,
Thunk.This.NonVirtual,
- Thunk.This.VCallOffsetOffset);
+ Thunk.This.VCallOffsetOffset,
+ /*IsReturnAdjustment*/false);
ThisStore->setOperand(0, AdjustedThisPtr);
if (!Thunk.Return.isEmpty()) {
@@ -335,7 +343,8 @@
llvm::Value *AdjustedThisPtr =
PerformTypeAdjustment(*this, LoadCXXThis(),
Thunk.This.NonVirtual,
- Thunk.This.VCallOffsetOffset);
+ Thunk.This.VCallOffsetOffset,
+ /*IsReturnAdjustment*/false);
CallArgList CallArgs;
Modified: cfe/trunk/test/CodeGenCXX/thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thunks.cpp?rev=163866&r1=163865&r2=163866&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/thunks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/thunks.cpp Thu Sep 13 20:45:09 2012
@@ -301,6 +301,32 @@
// CHECK: getelementptr inbounds i8* {{.*}}, i64 8
}
+// PR13832
+namespace Test13 {
+ struct B1 {
+ virtual B1 &foo1();
+ };
+ struct Pad1 {
+ virtual ~Pad1();
+ };
+ struct Proxy1 : Pad1, B1 {
+ virtual ~Proxy1();
+ };
+ struct D : virtual Proxy1 {
+ virtual ~D();
+ virtual D &foo1();
+ };
+ D& D::foo1() {
+ return *this;
+ }
+ // CHECK: define {{.*}} @_ZTcvn8_n32_v8_n24_N6Test131D4foo1Ev
+ // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8
+ // CHECK: getelementptr inbounds i8* {{.*}}, i64 -32
+ // CHECK: getelementptr inbounds i8* {{.*}}, i64 -24
+ // CHECK: getelementptr inbounds i8* {{.*}}, i64 8
+ // CHECK: ret %"struct.Test13::D"*
+}
+
/**** The following has to go at the end of the file ****/
// This is from Test5:
More information about the cfe-commits
mailing list