diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 41 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/vtable-pointer-initialization.cpp | 20 | 
3 files changed, 13 insertions, 50 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index b2991ade436..a21af413fd7 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -1549,7 +1549,6 @@ CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,  void  CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,                                            const CXXRecordDecl *NearestVBase, -                                         uint64_t BaseOffsetFromNearestVBase,                                           llvm::Constant *VTable,                                           const CXXRecordDecl *VTableClass) {    const CXXRecordDecl *RD = Base.getBase(); @@ -1577,31 +1576,21 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,        Builder.CreateConstInBoundsGEP2_64(VTable, 0, AddressPoint);    } -  llvm::Value *VTableField = LoadCXXThis(); -    // Compute where to store the address point. -  uint64_t NonVirtualOffset = BaseOffsetFromNearestVBase; - -  llvm::Value *VirtualOffset = 0; -  if (NearestVBase) { -    if (!CodeGenVTables::needsVTTParameter(CurGD)) { -      // Just get the vbase offset in the complete class. -      const ASTRecordLayout &Layout =  -        getContext().getASTRecordLayout(VTableClass); - -      NonVirtualOffset += Layout.getVBaseClassOffset(NearestVBase); -    } else { -      // We need to use the virtual base offset offset because the virtual base -      // might have a different offset in the most derived class. -      VirtualOffset = GetVirtualBaseClassOffset(VTableField, -                                                VTableClass, NearestVBase); -    } -  } +  llvm::Value *VTableField; +   +  if (CodeGenVTables::needsVTTParameter(CurGD) && NearestVBase) { +    // We need to use the virtual base offset offset because the virtual base +    // might have a different offset in the most derived class. +    VTableField = GetAddressOfBaseClass(LoadCXXThis(), VTableClass, RD,  +                                        /*NullCheckValue=*/false); +  } else { +    const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext()); -  if (NonVirtualOffset || VirtualOffset) +    VTableField = Builder.CreateBitCast(LoadCXXThis(), Int8PtrTy);      VTableField =  -      ApplyNonVirtualAndVirtualOffset(*this, VTableField, -                                      NonVirtualOffset, VirtualOffset); +      Builder.CreateConstInBoundsGEP1_64(VTableField, Base.getBaseOffset() / 8);   +  }    // Finally, store the address point.    const llvm::Type *AddressPointPtrTy = @@ -1613,7 +1602,6 @@ CodeGenFunction::InitializeVTablePointer(BaseSubobject Base,  void  CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,                                             const CXXRecordDecl *NearestVBase, -                                          uint64_t BaseOffsetFromNearestVBase,                                            bool BaseIsNonVirtualPrimaryBase,                                            llvm::Constant *VTable,                                            const CXXRecordDecl *VTableClass, @@ -1622,8 +1610,7 @@ CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,    // been set.    if (!BaseIsNonVirtualPrimaryBase) {      // Initialize the vtable pointer for this base. -    InitializeVTablePointer(Base, NearestVBase, BaseOffsetFromNearestVBase, -                            VTable, VTableClass); +    InitializeVTablePointer(Base, NearestVBase, VTable, VTableClass);    }    const CXXRecordDecl *RD = Base.getBase(); @@ -1660,7 +1647,6 @@ CodeGenFunction::InitializeVTablePointers(BaseSubobject Base,      InitializeVTablePointers(BaseSubobject(BaseDecl, BaseOffset),                                I->isVirtual() ? BaseDecl : NearestVBase, -                             I->isVirtual() ? 0 : BaseOffsetFromNearestVBase,                               BaseDeclIsNonVirtualPrimaryBase,                                VTable, VTableClass, VBases);    } @@ -1677,7 +1663,6 @@ void CodeGenFunction::InitializeVTablePointers(const CXXRecordDecl *RD) {    // Initialize the vtable pointers for this class and all of its bases.    VisitedVirtualBasesSetTy VBases;    InitializeVTablePointers(BaseSubobject(RD, 0), /*NearestVBase=*/0,  -                           /*BaseOffsetFromNearestVBase=*/0,                             /*BaseIsNonVirtualPrimaryBase=*/false,                              VTable, RD, VBases);  } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 12e37e42d72..c43e0006e69 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -536,14 +536,12 @@ public:    ///    void InitializeVTablePointer(BaseSubobject Base,                                  const CXXRecordDecl *NearestVBase, -                               uint64_t BaseOffsetFromNearestVBase,                                 llvm::Constant *VTable,                                 const CXXRecordDecl *VTableClass);    typedef llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBasesSetTy;    void InitializeVTablePointers(BaseSubobject Base,                                   const CXXRecordDecl *NearestVBase, -                                uint64_t BaseOffsetFromNearestVBase,                                  bool BaseIsNonVirtualPrimaryBase,                                  llvm::Constant *VTable,                                  const CXXRecordDecl *VTableClass, diff --git a/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp b/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp index ca8fb9be88a..75620ab8e62 100644 --- a/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp +++ b/clang/test/CodeGenCXX/vtable-pointer-initialization.cpp @@ -55,23 +55,3 @@ void f() { B b; }  // CHECK: store i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2)  // CHECK: call void @_ZN5FieldC1Ev  // CHECK: ret void - -namespace Test1 { - -// Test that we don't assert when initializing the vtable pointers in C. -struct A { -  virtual void a(); -  int i; -}; - -struct B : virtual A { -  virtual void b(); -}; - -struct C : A, virtual B { -  virtual void c(); -  C(); -}; - -C::C() { } -}  | 

