From bbfd5babab059af14eed20b63b2aabedaa6a6ac7 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 5 Feb 2011 18:48:55 +0000 Subject: [PATCH] Pass a 'ForVTable' flag to GetAddrOfThunk and pass it along to GetOrCreateLLVMFunction so that we won't assert when building a thunk for an implicit virtual member function that is not marked used. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@124967 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVTables.cpp | 11 ++++---- lib/CodeGen/CodeGenModule.h | 3 ++- .../vtable-available-externally.cpp | 26 +++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index eadfe9f146..27b4432920 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -2451,7 +2451,8 @@ CodeGenVTables::getAddressPoint(BaseSubobject Base, const CXXRecordDecl *RD) { } llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, - const ThunkInfo &Thunk) { + const ThunkInfo &Thunk, + bool ForVTable) { const CXXMethodDecl *MD = cast(GD.getDecl()); // Compute the mangled name. @@ -2463,7 +2464,7 @@ llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, getCXXABI().getMangleContext().mangleThunk(MD, Thunk, Name); const llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(GD); - return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/false); + return GetOrCreateLLVMFunction(Name, Ty, GD, ForVTable); } static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF, @@ -2681,7 +2682,7 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk) { - llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk); + llvm::Constant *Entry = CGM.GetAddrOfThunk(GD, Thunk, /*ForVTable=*/false); // Strip off a bitcast if we got one back. if (llvm::ConstantExpr *CE = dyn_cast(Entry)) { @@ -2701,7 +2702,7 @@ void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk) // Remove the name from the old thunk function and get a new thunk. OldThunkFn->setName(llvm::StringRef()); - Entry = CGM.GetAddrOfThunk(GD, Thunk); + Entry = CGM.GetAddrOfThunk(GD, Thunk, /*ForVTable=*/false); // If needed, replace the old thunk with a bitcast. if (!OldThunkFn->use_empty()) { @@ -2912,7 +2913,7 @@ CodeGenVTables::CreateVTableInitializer(const CXXRecordDecl *RD, VTableThunks[NextVTableThunkIndex].first == I) { const ThunkInfo &Thunk = VTableThunks[NextVTableThunkIndex].second; - Init = CGM.GetAddrOfThunk(GD, Thunk); + Init = CGM.GetAddrOfThunk(GD, Thunk, /*ForVTable=*/true); NextVTableThunkIndex++; } else { diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 1ed56d5b92..7b6e12358d 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -325,7 +325,8 @@ public: llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); /// GetAddrOfThunk - Get the address of the thunk for the given global decl. - llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk); + llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk, + bool ForVTable); /// GetWeakRefReference - Get a reference to the target of VD. llvm::Constant *GetWeakRefReference(const ValueDecl *VD); diff --git a/test/CodeGenCXX/vtable-available-externally.cpp b/test/CodeGenCXX/vtable-available-externally.cpp index 594709d589..f56e3d147f 100644 --- a/test/CodeGenCXX/vtable-available-externally.cpp +++ b/test/CodeGenCXX/vtable-available-externally.cpp @@ -118,3 +118,29 @@ struct B : A { B::~B() { } } + +// Check that we don't assert on this test. +namespace Test6 { + +struct A { + virtual ~A(); + int a; +}; + +struct B { + virtual ~B(); + int b; +}; + +struct C : A, B { + C(); +}; + +struct D : C { + virtual void f(); + D(); +}; + +D::D() { } + +} -- 2.40.0