r212125 - MS ABI: Reference MSVC RTTI from the VFTable

Timur Iskhodzhanov timurrrr at google.com
Tue Jul 8 06:15:11 PDT 2014


Filed
http://llvm.org/bugs/show_bug.cgi?id=20244
to track the progress.

2014-07-08 16:28 GMT+04:00 Timur Iskhodzhanov <timurrrr at google.com>:
> I'm trying to understand how to fix the ASan/Windows breakage wrt vftables.
>
> Here's what David told me on the r212138 thread:
> 2014-07-08 4:39 GMT+04:00 David Majnemer <david.majnemer at gmail.com>:
>> ASAN replaces one internal global with another. Because the new symbol
>> isn't in a Comdat, it's alias isn't either.  This makes the alias a
>> strong definition.
>
> After rethinking this a bit, I'm puzzled.
> Not only we need to correctly link no-rtti with rtti-enabled TUs but we
> should also handle asan vs no-asan TUs.
> ASan increases the size of globals by adding redzones.
> It looks like an internal GV for a vftable in a (asan enabled, no-rtti)
> configuration will be *larger* than the same vftable in a
> (no-asan,rtti-enabled) configuration and the linking process will cause bad
> result.
> That said, I think we have to disable instrumentation of vftables on Windows
> as long as we want to support mixing rtti- with no-rtti TUs or asan with
> no-asan TUs.
> Are we on the same page here?
>
> If we agree that we can't add redzones to vftables, we should adjust
> AddressSanitizerModule::ShouldInstrumentGlobal(GV) to handle this.
> The problem is that those GVs are unnamed.
> Is there a condition that's only true for the internal vftable GVs so I can
> write an "if()"?
> I think "if (G->hasComdat() && G->getLinkage() == InternalLinkage)" is a too
> wide condition.
> Or can we name these internal GVs somehow to make them easy to filter out?
> E.g. "\02?_7blah"?
>
>
> 2014-07-02 0:30 GMT+04:00 David Majnemer <david.majnemer at gmail.com>:
>
>> Author: majnemer
>> Date: Tue Jul  1 15:30:31 2014
>> New Revision: 212125
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=212125&view=rev
>> Log:
>> MS ABI: Reference MSVC RTTI from the VFTable
>>
>> The pointer for a class's RTTI data comes right before the VFTable but
>> has no name.  To be properly compatible with this, we do the following:
>> * Create a single GlobalVariable which holds the contents of the VFTable
>>   _and_ the pointer to the RTTI data.
>> * Create a GlobalAlias, with appropriate linkage/visibility, that points
>>   just after the RTTI data pointer.  This ensures that the VFTable
>>   symbol will always refer to VFTable data.
>> * Create a Comdat with a "Largest" SelectionKind and stick the private
>>   GlobalVariable in it.  By transitivity, the GlobalAlias will be a
>>   member of the Comdat group.  Using "Largest" ensures that foreign
>>   definitions without an RTTI data pointer will _not_ be chosen in the
>>   final linked image.
>>
>> Whether or not we emit RTTI data depends on several things:
>> * The -fno-rtti flag implies that we should never not emit a pointer to
>>   RTTI data before the VFTable.
>> * __declspec(dllimport) brings in the VFTable from a remote DLL. Use an
>>   available_externally GlobalVariable to provide a local definition of
>>   the VFTable.  This means that we won't have any available_externally
>>   definitions of things like complete object locators.  This is
>>   acceptable because they are never directly referenced.
>>
>> To my knowledge, this completes the implementation of MSVC RTTI code
>> generation.
>>
>> Further semantic work should be done to properly support /GR-.
>>
>> Modified:
>>     cfe/trunk/lib/AST/VTableBuilder.cpp
>>     cfe/trunk/lib/CodeGen/CGVTables.cpp
>>     cfe/trunk/lib/CodeGen/CGVTables.h
>>     cfe/trunk/lib/CodeGen/CodeGenModule.h
>>     cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>>     cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
>>     cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp
>>     cfe/trunk/test/CodeGenCXX/dllexport.cpp
>>
>> Modified: cfe/trunk/lib/AST/VTableBuilder.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/VTableBuilder.cpp?rev=212125&r1=212124&r2=212125&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/AST/VTableBuilder.cpp (original)
>> +++ cfe/trunk/lib/AST/VTableBuilder.cpp Tue Jul  1 15:30:31 2014
>> @@ -2574,6 +2574,12 @@ public:
>>
>> MostDerivedClassLayout(Context.getASTRecordLayout(MostDerivedClass)),
>>          WhichVFPtr(*Which),
>>          Overriders(MostDerivedClass, CharUnits(), MostDerivedClass) {
>> +    // Only include the RTTI component if we know that we will provide a
>> +    // definition of the vftable.
>> +    if (Context.getLangOpts().RTTI &&
>> +        !MostDerivedClass->hasAttr<DLLImportAttr>())
>> +      Components.push_back(VTableComponent::MakeRTTI(MostDerivedClass));
>> +
>>      LayoutVFTable();
>>
>>      if (Context.getLangOpts().DumpVTableLayouts)
>> @@ -2915,7 +2921,8 @@ void VFTableBuilder::AddMethods(BaseSubo
>>      // it requires return adjustment. Insert the method info for this
>> method.
>>      unsigned VBIndex =
>>          LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase)
>> : 0;
>> -    MethodInfo MI(VBIndex, Components.size());
>> +    MethodInfo MI(VBIndex, Context.getLangOpts().RTTI ? Components.size()
>> - 1
>> +                                                      :
>> Components.size());
>>
>>      assert(!MethodInfoMap.count(MD) &&
>>             "Should not have method info for this method yet!");
>>
>> Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=212125&r1=212124&r2=212125&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGVTables.cpp Tue Jul  1 15:30:31 2014
>> @@ -431,12 +431,10 @@ void CodeGenVTables::EmitThunks(GlobalDe
>>      emitThunk(GD, (*ThunkInfoVector)[I], /*ForVTable=*/false);
>>  }
>>
>> -llvm::Constant *
>> -CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD,
>> -                                        const VTableComponent
>> *Components,
>> -                                        unsigned NumComponents,
>> -                                const VTableLayout::VTableThunkTy
>> *VTableThunks,
>> -                                        unsigned NumVTableThunks) {
>> +llvm::Constant *CodeGenVTables::CreateVTableInitializer(
>> +    const CXXRecordDecl *RD, const VTableComponent *Components,
>> +    unsigned NumComponents, const VTableLayout::VTableThunkTy
>> *VTableThunks,
>> +    unsigned NumVTableThunks, llvm::Constant *RTTI) {
>>    SmallVector<llvm::Constant *, 64> Inits;
>>
>>    llvm::Type *Int8PtrTy = CGM.Int8PtrTy;
>> @@ -444,9 +442,6 @@ CodeGenVTables::CreateVTableInitializer(
>>    llvm::Type *PtrDiffTy =
>>      CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
>>
>> -  QualType ClassType = CGM.getContext().getTagDeclType(RD);
>> -  llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(ClassType);
>> -
>>    unsigned NextVTableThunkIndex = 0;
>>
>>    llvm::Constant *PureVirtualFn = nullptr, *DeletedVirtualFn = nullptr;
>> @@ -594,13 +589,14 @@ CodeGenVTables::GenerateConstructionVTab
>>    // V-tables are always unnamed_addr.
>>    VTable->setUnnamedAddr(true);
>>
>> +  llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
>> +      CGM.getContext().getTagDeclType(Base.getBase()));
>> +
>>    // Create and set the initializer.
>> -  llvm::Constant *Init =
>> -    CreateVTableInitializer(Base.getBase(),
>> -                            VTLayout->vtable_component_begin(),
>> -                            VTLayout->getNumVTableComponents(),
>> -                            VTLayout->vtable_thunk_begin(),
>> -                            VTLayout->getNumVTableThunks());
>> +  llvm::Constant *Init = CreateVTableInitializer(
>> +      Base.getBase(), VTLayout->vtable_component_begin(),
>> +      VTLayout->getNumVTableComponents(), VTLayout->vtable_thunk_begin(),
>> +      VTLayout->getNumVTableThunks(), RTTI);
>>    VTable->setInitializer(Init);
>>
>>    return VTable;
>>
>> Modified: cfe/trunk/lib/CodeGen/CGVTables.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.h?rev=212125&r1=212124&r2=212125&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGVTables.h (original)
>> +++ cfe/trunk/lib/CodeGen/CGVTables.h Tue Jul  1 15:30:31 2014
>> @@ -61,11 +61,10 @@ public:
>>    /// decl.
>>    /// \param Components - The vtable components; this is really an array
>> of
>>    /// VTableComponents.
>> -  llvm::Constant *CreateVTableInitializer(const CXXRecordDecl *RD,
>> -                                          const VTableComponent
>> *Components,
>> -                                          unsigned NumComponents,
>> -                                const VTableLayout::VTableThunkTy
>> *VTableThunks,
>> -                                          unsigned NumVTableThunks);
>> +  llvm::Constant *CreateVTableInitializer(
>> +      const CXXRecordDecl *RD, const VTableComponent *Components,
>> +      unsigned NumComponents, const VTableLayout::VTableThunkTy
>> *VTableThunks,
>> +      unsigned NumVTableThunks, llvm::Constant *RTTI);
>>
>>    CodeGenVTables(CodeGenModule &CGM);
>>
>>
>> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=212125&r1=212124&r2=212125&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
>> +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Jul  1 15:30:31 2014
>> @@ -750,8 +750,8 @@ public:
>>    /// \brief Gets or a creats a Microsoft TypeDescriptor.
>>    llvm::Constant *getMSTypeDescriptor(QualType Ty);
>>    /// \brief Gets or a creats a Microsoft CompleteObjectLocator.
>> -  llvm::GlobalVariable *getMSCompleteObjectLocator(const CXXRecordDecl
>> *RD,
>> -                                                   const VPtrInfo *Info);
>> +  llvm::Constant *getMSCompleteObjectLocator(const CXXRecordDecl *RD,
>> +                                             const VPtrInfo *Info);
>>
>>    /// Gets the address of a block which requires no captures.
>>    llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, const char
>> *);
>>
>> Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=212125&r1=212124&r2=212125&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Jul  1 15:30:31 2014
>> @@ -1182,11 +1182,13 @@ void ItaniumCXXABI::emitVTableDefinition
>>    ItaniumVTableContext &VTContext = CGM.getItaniumVTableContext();
>>    const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);
>>    llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
>> +  llvm::Constant *RTTI =
>> +      CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
>>
>>    // Create and set the initializer.
>>    llvm::Constant *Init = CGVT.CreateVTableInitializer(
>>        RD, VTLayout.vtable_component_begin(),
>> VTLayout.getNumVTableComponents(),
>> -      VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks());
>> +      VTLayout.vtable_thunk_begin(), VTLayout.getNumVTableThunks(),
>> RTTI);
>>    VTable->setInitializer(Init);
>>
>>    // Set the correct linkage.
>>
>> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=212125&r1=212124&r2=212125&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Jul  1 15:30:31 2014
>> @@ -403,9 +403,11 @@ public:
>>
>>  private:
>>    typedef std::pair<const CXXRecordDecl *, CharUnits> VFTableIdTy;
>> -  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *>
>> VFTablesMapTy;
>> +  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalVariable *>
>> VTablesMapTy;
>> +  typedef llvm::DenseMap<VFTableIdTy, llvm::GlobalValue *> VFTablesMapTy;
>>    /// \brief All the vftables that have been referenced.
>>    VFTablesMapTy VFTablesMap;
>> +  VTablesMapTy VTablesMap;
>>
>>    /// \brief This set holds the record decls we've deferred vtable
>> emission for.
>>    llvm::SmallPtrSet<const CXXRecordDecl *, 4> DeferredVFTables;
>> @@ -1051,26 +1053,22 @@ void MicrosoftCXXABI::emitVTableDefiniti
>>                                              const CXXRecordDecl *RD) {
>>    MicrosoftVTableContext &VFTContext = CGM.getMicrosoftVTableContext();
>>    VPtrInfoVector VFPtrs = VFTContext.getVFPtrOffsets(RD);
>> -  llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
>>
>>    for (VPtrInfo *Info : VFPtrs) {
>>      llvm::GlobalVariable *VTable = getAddrOfVTable(RD,
>> Info->FullOffsetInMDC);
>>      if (VTable->hasInitializer())
>>        continue;
>> -    if (getContext().getLangOpts().RTTI)
>> -      CGM.getMSCompleteObjectLocator(RD, Info);
>> +
>> +    llvm::Constant *RTTI = CGM.getMSCompleteObjectLocator(RD, Info);
>>
>>      const VTableLayout &VTLayout =
>>        VFTContext.getVFTableLayout(RD, Info->FullOffsetInMDC);
>>      llvm::Constant *Init = CGVT.CreateVTableInitializer(
>>          RD, VTLayout.vtable_component_begin(),
>>          VTLayout.getNumVTableComponents(), VTLayout.vtable_thunk_begin(),
>> -        VTLayout.getNumVTableThunks());
>> -    VTable->setInitializer(Init);
>> -
>> -    VTable->setLinkage(Linkage);
>> +        VTLayout.getNumVTableThunks(), RTTI);
>>
>> -    CGM.setGlobalVisibility(VTable, RD);
>> +    VTable->setInitializer(Init);
>>    }
>>  }
>>
>> @@ -1079,8 +1077,9 @@ llvm::Value *MicrosoftCXXABI::getVTableA
>>      const CXXRecordDecl *NearestVBase, bool &NeedsVirtualOffset) {
>>    NeedsVirtualOffset = (NearestVBase != nullptr);
>>
>> -  llvm::Value *VTableAddressPoint =
>> -      getAddrOfVTable(VTableClass, Base.getBaseOffset());
>> +  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
>> +  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
>> +  llvm::GlobalValue *VTableAddressPoint = VFTablesMap[ID];
>>    if (!VTableAddressPoint) {
>>      assert(Base.getBase()->getNumVBases() &&
>>
>> !CGM.getContext().getASTRecordLayout(Base.getBase()).hasOwnVFPtr());
>> @@ -1097,9 +1096,11 @@ static void mangleVFTableName(MicrosoftM
>>
>>  llvm::Constant *MicrosoftCXXABI::getVTableAddressPointForConstExpr(
>>      BaseSubobject Base, const CXXRecordDecl *VTableClass) {
>> -  llvm::Constant *VTable = getAddrOfVTable(VTableClass,
>> Base.getBaseOffset());
>> -  assert(VTable && "Couldn't find a vftable for the given base?");
>> -  return VTable;
>> +  (void)getAddrOfVTable(VTableClass, Base.getBaseOffset());
>> +  VFTableIdTy ID(VTableClass, Base.getBaseOffset());
>> +  llvm::GlobalValue *VFTable = VFTablesMap[ID];
>> +  assert(VFTable && "Couldn't find a vftable for the given base?");
>> +  return VFTable;
>>  }
>>
>>  llvm::GlobalVariable *MicrosoftCXXABI::getAddrOfVTable(const
>> CXXRecordDecl *RD,
>> @@ -1108,9 +1109,9 @@ llvm::GlobalVariable *MicrosoftCXXABI::g
>>    // shouldn't be used in the given record type. We want to cache this
>> result in
>>    // VFTablesMap, thus a simple zero check is not sufficient.
>>    VFTableIdTy ID(RD, VPtrOffset);
>> -  VFTablesMapTy::iterator I;
>> +  VTablesMapTy::iterator I;
>>    bool Inserted;
>> -  std::tie(I, Inserted) = VFTablesMap.insert(std::make_pair(ID,
>> nullptr));
>> +  std::tie(I, Inserted) = VTablesMap.insert(std::make_pair(ID, nullptr));
>>    if (!Inserted)
>>      return I->second;
>>
>> @@ -1140,21 +1141,73 @@ llvm::GlobalVariable *MicrosoftCXXABI::g
>>    for (size_t J = 0, F = VFPtrs.size(); J != F; ++J) {
>>      if (VFPtrs[J]->FullOffsetInMDC != VPtrOffset)
>>        continue;
>> +    SmallString<256> VFTableName;
>> +    mangleVFTableName(getMangleContext(), RD, VFPtrs[J], VFTableName);
>> +    StringRef VTableName = VFTableName;
>>
>> -    llvm::ArrayType *ArrayType = llvm::ArrayType::get(
>> -        CGM.Int8PtrTy,
>> +    uint64_t NumVTableSlots =
>>          VTContext.getVFTableLayout(RD, VFPtrs[J]->FullOffsetInMDC)
>> -            .getNumVTableComponents());
>> +            .getNumVTableComponents();
>> +    llvm::GlobalValue::LinkageTypes VTableLinkage =
>> +        llvm::GlobalValue::ExternalLinkage;
>> +    llvm::ArrayType *VTableType =
>> +        llvm::ArrayType::get(CGM.Int8PtrTy, NumVTableSlots);
>> +    if (getContext().getLangOpts().RTTI) {
>> +      VTableLinkage = llvm::GlobalValue::PrivateLinkage;
>> +      VTableName = "";
>> +    }
>>
>> -    SmallString<256> Name;
>> -    mangleVFTableName(getMangleContext(), RD, VFPtrs[J], Name);
>> -    VTable = CGM.CreateOrReplaceCXXRuntimeVariable(
>> -        Name.str(), ArrayType, llvm::GlobalValue::ExternalLinkage);
>> -    VTable->setUnnamedAddr(true);
>> -    if (RD->hasAttr<DLLImportAttr>())
>> -
>> VTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
>> -    else if (RD->hasAttr<DLLExportAttr>())
>> -
>> VTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
>> +    VTable = CGM.getModule().getNamedGlobal(VFTableName);
>> +    if (!VTable) {
>> +      llvm::GlobalValue *VFTable = VTable = new llvm::GlobalVariable(
>> +          CGM.getModule(), VTableType, /*isConstant=*/true,
>> VTableLinkage,
>> +          /*Initializer=*/nullptr, VTableName);
>> +      VTable->setUnnamedAddr(true);
>> +      if (getContext().getLangOpts().RTTI &&
>> !RD->hasAttr<DLLImportAttr>()) {
>> +        llvm::Value *GEPIndices[] = {llvm::ConstantInt::get(CGM.IntTy,
>> 0),
>> +                                     llvm::ConstantInt::get(CGM.IntTy,
>> 1)};
>> +        llvm::Constant *VTableGEP =
>> +            llvm::ConstantExpr::getInBoundsGetElementPtr(VTable,
>> GEPIndices);
>> +        VFTable = llvm::GlobalAlias::create(
>> +
>> cast<llvm::SequentialType>(VTableGEP->getType())->getElementType(),
>> +            /*AddressSpace=*/0, llvm::GlobalValue::ExternalLinkage,
>> +            VFTableName.str(), VTableGEP, &CGM.getModule());
>> +      } else {
>> +        VTable->setName(VFTableName.str());
>> +      }
>> +
>> +      VFTable->setUnnamedAddr(true);
>> +      if (RD->hasAttr<DLLImportAttr>())
>> +
>> VFTable->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass);
>> +      else if (RD->hasAttr<DLLExportAttr>())
>> +
>> VFTable->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
>> +
>> +      llvm::GlobalValue::LinkageTypes VFTableLinkage =
>> CGM.getVTableLinkage(RD);
>> +      if (VFTable != VTable) {
>> +        if
>> (llvm::GlobalValue::isAvailableExternallyLinkage(VFTableLinkage)) {
>> +          // AvailableExternally implies that we grabbed the data from
>> another
>> +          // executable.  No need to stick the alias in a Comdat.
>> +        } else if (llvm::GlobalValue::isLocalLinkage(VFTableLinkage)) {
>> +          // If it's local, it means that the virtual function table
>> can't be
>> +          // referenced in another translation unit. No need to stick the
>> alias
>> +          // in a Comdat.
>> +        } else if (llvm::GlobalValue::isWeakODRLinkage(VFTableLinkage) ||
>> +
>> llvm::GlobalValue::isLinkOnceODRLinkage(VFTableLinkage)) {
>> +          // The alias is going to be dropped into a Comdat, no need to
>> make it
>> +          // weak.
>> +          VFTableLinkage = llvm::GlobalValue::ExternalLinkage;
>> +          llvm::Comdat *C =
>> +              CGM.getModule().getOrInsertComdat(VFTable->getName());
>> +          C->setSelectionKind(llvm::Comdat::Largest);
>> +          VTable->setComdat(C);
>> +        } else {
>> +          llvm_unreachable("unexpected linkage for vftable!");
>> +        }
>> +      }
>> +      VFTable->setLinkage(VFTableLinkage);
>> +      CGM.setGlobalVisibility(VFTable, RD);
>> +      VFTablesMap[ID] = VFTable;
>> +    }
>>      break;
>>    }
>>
>>
>> Modified: cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp?rev=212125&r1=212124&r2=212125&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/MicrosoftRTTI.cpp Tue Jul  1 15:30:31 2014
>> @@ -505,8 +505,10 @@ llvm::Constant *CodeGenModule::getMSType
>>        Int8PtrTy);
>>  }
>>
>> -llvm::GlobalVariable *
>> +llvm::Constant *
>>  CodeGenModule::getMSCompleteObjectLocator(const CXXRecordDecl *RD,
>>                                            const VPtrInfo *Info) {
>> +  if (!getLangOpts().RTTI)
>> +    return llvm::Constant::getNullValue(Int8PtrTy);
>>    return MSRTTIBuilder(*this, RD).getCompleteObjectLocator(Info);
>>  }
>>
>> Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=212125&r1=212124&r2=212125&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original)
>> +++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Tue Jul  1 15:30:31 2014
>> @@ -24,6 +24,9 @@ struct External { int v; };
>>  #define INSTVAR(var) template int var;
>>  #define INST(func) template void func();
>>
>> +// The vftable for struct W is comdat largest because we have RTTI.
>> +// M32-DAG: $"\01??_7W@@6B@" = comdat largest
>> +
>>
>>
>> //===----------------------------------------------------------------------===//
>>  // Globals
>> @@ -518,7 +521,8 @@ struct __declspec(dllexport) W { virtual
>>  // Copy ctor:
>>  // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W*
>> @"\01??0W@@QAE at ABU0@@Z"
>>  // vftable:
>> -// M32-DAG: @"\01??_7W@@6B@" = weak_odr dllexport unnamed_addr constant
>> [1 x i8*] [i8* bitcast (void (%struct.W*)* @"\01?foo at W@@UAEXXZ" to i8*)]
>> +// M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant [2 x i8*]
>> [i8* bitcast (%MSRTTICompleteObjectLocator* @"\01??_R4W@@6B@" to i8*), i8*
>> bitcast (void (%struct.W*)* @"\01?foo at W@@UAEXXZ" to i8*)], comdat
>> $"\01??_7W@@6B@"
>> +// M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias getelementptr
>> inbounds ([2 x i8*]* [[W_VTABLE]], i32 0, i32 1), comdat $"\01??_7W@@6B@"
>>  // G32-DAG: @_ZTV1W = weak_odr dllexport unnamed_addr constant [3 x i8*]
>> [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void
>> (%struct.W*)* @_ZN1W3fooEv to i8*)]
>>
>>  struct __declspec(dllexport) X : public virtual W {};
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>



More information about the cfe-commits mailing list