From: Petr Hosek Date: Mon, 11 Feb 2019 20:13:42 +0000 (+0000) Subject: [CodeGen] Set construction vtable visibility after creating initializer X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b72beebc7280d5ec2688cad5b1f476d8eac5a216;p=clang [CodeGen] Set construction vtable visibility after creating initializer We must only set the construction vtable visibility after we create the vtable initializer, otherwise the global value will be treated as declaration rather than definition and the visibility won't be set. Differential Revision: https://reviews.llvm.org/D58010 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@353742 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp index a7b81a01f7..3cb3d35448 100644 --- a/lib/CodeGen/CGVTables.cpp +++ b/lib/CodeGen/CGVTables.cpp @@ -761,7 +761,6 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, // Create the variable that will hold the construction vtable. llvm::GlobalVariable *VTable = CGM.CreateOrReplaceCXXRuntimeVariable(Name, VTType, Linkage, Align); - CGM.setGVProperties(VTable, RD); // V-tables are always unnamed_addr. VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global); @@ -775,6 +774,11 @@ CodeGenVTables::GenerateConstructionVTable(const CXXRecordDecl *RD, createVTableInitializer(components, *VTLayout, RTTI); components.finishAndSetAsInitializer(VTable); + // Set properties only after the initializer has been set to ensure that the + // GV is treated as definition and not declaration. + assert(!VTable->isDeclaration() && "Shouldn't set properties on declaration"); + CGM.setGVProperties(VTable, RD); + CGM.EmitVTableTypeMetadata(VTable, *VTLayout.get()); return VTable; diff --git a/test/CodeGen/construction-vtable-visibility.cpp b/test/CodeGen/construction-vtable-visibility.cpp new file mode 100644 index 0000000000..127e1b1905 --- /dev/null +++ b/test/CodeGen/construction-vtable-visibility.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple x86_64-linux-unknown -fvisibility hidden -emit-llvm %s -o - | FileCheck %s + +struct Base {}; + +class Parent1 : virtual public Base {}; + +class Parent2 : virtual public Base {}; + +class Child : public Parent1, public Parent2 {}; + +void test() { + Child x; +} + +// CHECK: @_ZTC5Child0_7Parent1 = linkonce_odr hidden unnamed_addr constant +// CHECK: @_ZTC5Child8_7Parent2 = linkonce_odr hidden unnamed_addr constant