From: Reid Kleckner Date: Mon, 20 Jul 2015 20:35:30 +0000 (+0000) Subject: Fix a case where we forgot to make a static local variable comdat X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c4eae4ee72586c401778ac892c4467ada53befbd;p=clang Fix a case where we forgot to make a static local variable comdat Sometimes we can provide an initializer for static locals, in which case we sometimes might need to change the type. Changing the type requires making a new LLVM GlobalVariable, and in this codepath we were forgetting to transfer the comdat. Fixes PR23838. Patch by Ivan Garramona. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@242704 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 96aa8c68e0..ebd1776e50 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -311,6 +311,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, OldGV->getThreadLocalMode(), CGM.getContext().getTargetAddressSpace(D.getType())); GV->setVisibility(OldGV->getVisibility()); + GV->setComdat(OldGV->getComdat()); // Steal the name of the old global GV->takeName(OldGV); diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp index 25489f022c..255251e707 100644 --- a/test/CodeGenCXX/static-init.cpp +++ b/test/CodeGenCXX/static-init.cpp @@ -9,6 +9,7 @@ // CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat, align // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat{{$}} // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16 +// CHECK: @_ZZN5test414useStaticLocalEvE3obj = linkonce_odr global %"struct.test4::HasVTable" zeroinitializer, comdat, align 8 struct A { A(); @@ -154,3 +155,19 @@ namespace test3 { // CHECK-LABEL: define void @_ZN5test31BC2Ev( // CHECK-LABEL: define void @_ZN5test31BC1Ev( } + +// We forgot to set the comdat when replacing the global with a different type. +namespace test4 { +struct HasVTable { + virtual void f(); +}; +inline HasVTable &useStaticLocal() { + static HasVTable obj; + return obj; +} +void useit() { + useStaticLocal(); +} +// CHECK: define linkonce_odr dereferenceable(8) %"struct.test4::HasVTable"* @_ZN5test414useStaticLocalEv() +// CHECK: ret %"struct.test4::HasVTable"* @_ZZN5test414useStaticLocalEvE3obj +}