Index: clang/lib/CodeGen/CGVTables.cpp =================================================================== --- clang/lib/CodeGen/CGVTables.cpp +++ clang/lib/CodeGen/CGVTables.cpp @@ -761,7 +761,6 @@ // 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 @@ 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; Index: clang/test/CodeGen/construction-vtable-visibility.cpp =================================================================== --- /dev/null +++ clang/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