From 04da2385cfbc91dbbb92e7594348287e11226bcf Mon Sep 17 00:00:00 2001 From: Yaron Keren Date: Wed, 29 Jul 2015 15:42:28 +0000 Subject: [PATCH] In case of an existing GlobalVariable, the comdat is created using the name of the new GV (usually NAME.1) instead of the correct NAME of the old GV. Moving comdat creation after GV replacement solves this. Patch + testcase. Reviewed by Reid Kleckner. http://reviews.llvm.org/D11594 llvm-svn: 243525 --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 6 +++--- .../CodeGenCXX/vtable-key-function-win-comdat.cpp | 25 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGenCXX/vtable-key-function-win-comdat.cpp diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index ed29fc2..0b65088 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -2837,9 +2837,6 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) { new llvm::GlobalVariable(M, Init->getType(), /*Constant=*/true, Linkage, Init, Name); - if (CGM.supportsCOMDAT() && GV->isWeakForLinker()) - GV->setComdat(M.getOrInsertComdat(GV->getName())); - // If there's already an old global variable, replace it with the new one. if (OldGV) { GV->takeName(OldGV); @@ -2849,6 +2846,9 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) { OldGV->eraseFromParent(); } + if (CGM.supportsCOMDAT() && GV->isWeakForLinker()) + GV->setComdat(M.getOrInsertComdat(GV->getName())); + // The Itanium ABI specifies that type_info objects must be globally // unique, with one exception: if the type is an incomplete class // type or a (possibly indirect) pointer to one. That exception diff --git a/clang/test/CodeGenCXX/vtable-key-function-win-comdat.cpp b/clang/test/CodeGenCXX/vtable-key-function-win-comdat.cpp new file mode 100644 index 0000000..3dd1be7 --- /dev/null +++ b/clang/test/CodeGenCXX/vtable-key-function-win-comdat.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 %s -triple=x86_64-pc-windows-gnu -emit-llvm -o - | FileCheck %s + +namespace std { class type_info; } +extern void use(const std::type_info &rtti); + +struct Test1a { + Test1a(); + virtual void foo(); + virtual void bar(); +}; + +// V-table needs to be defined weakly. +Test1a::Test1a() { use(typeid(Test1a)); } +// This defines the key function. +inline void Test1a::foo() {} + +// CHECK: $_ZTV6Test1a = comdat any +// CHECK: $_ZTS6Test1a = comdat any +// CHECK: $_ZTI6Test1a = comdat any +// CHECK-NOT: $_ZTS6Test1a.1 = comdat any +// CHECK-NOT: $_ZTI6Test1a.1 = comdat any + +// CHECK: @_ZTV6Test1a = linkonce_odr unnamed_addr constant {{.*}} ({ i8*, i8* }* @_ZTI6Test1a to i8*) +// CHECK: @_ZTS6Test1a = linkonce_odr constant +// CHECK: @_ZTI6Test1a = linkonce_odr constant {{.*}} [8 x i8]* @_ZTS6Test1a -- 2.7.4