From: Rafael Espindola Date: Tue, 16 Dec 2014 21:00:30 +0000 (+0000) Subject: Put static local variables of inline functions in the function comdat. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e083843a3ed6314cd84544bec2e5b2bce42d522a;p=clang Put static local variables of inline functions in the function comdat. The variable (and the GV) is only ever used if the function is. Putting it in the function's comdat make it easier for the linker to discard them. The motivating example is struct S { static const int x; }; // const int S::x = 42; inline const int *f() { static const int y = S::x; return &y; } const int *g() { return f(); } With S::x commented out, _ZZ1fvE1y is a variable with a guard variable that is initialized by f. With S::x present, _ZZ1fvE1y is a constant. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@224369 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index fd299d14c1..8d74faf179 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -1711,8 +1711,10 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF, // The ABI says: It is suggested that it be emitted in the same COMDAT group // as the associated data object - if (!D.isLocalVarDecl() && var->isWeakForLinker() && CGM.supportsCOMDAT()) { - llvm::Comdat *C = CGM.getModule().getOrInsertComdat(var->getName()); + if (var->isWeakForLinker() && CGM.supportsCOMDAT()) { + StringRef ComdatName = + D.isLocalVarDecl() ? CGF.CurFn->getName() : var->getName(); + llvm::Comdat *C = CGM.getModule().getOrInsertComdat(ComdatName); guard->setComdat(C); var->setComdat(C); CGF.CurFn->setComdat(C); diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp index a9debe3de7..262d750e09 100644 --- a/test/CodeGenCXX/static-init.cpp +++ b/test/CodeGenCXX/static-init.cpp @@ -7,10 +7,8 @@ // CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4 // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16 -// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0 -// CHECK-NOT: comdat -// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0 -// CHECK-NOT: comdat +// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat $_Z2h2v +// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat $_Z2h2v struct A { A(); @@ -37,8 +35,7 @@ void h() { static const int i = a(); } -// CHECK: define linkonce_odr void @_Z2h2v() -// CHECK-NOT: comdat +// CHECK: define linkonce_odr void @_Z2h2v() {{.*}} comdat $_Z2h2v inline void h2() { static int i = a(); }