[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