From 112c967bd5c862a0f5d7913aa06700c048807db8 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 2 Nov 2010 21:04:24 +0000 Subject: [PATCH] Ensure that static local variables in function templates inherit the visibility of their function. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118065 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDecl.cpp | 6 +++++- lib/CodeGen/CodeGenModule.cpp | 7 +++++++ lib/CodeGen/ItaniumCXXABI.cpp | 4 ++++ test/CodeGenCXX/visibility.cpp | 17 +++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index e381e97947..5ac8508375 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -172,6 +172,8 @@ CodeGenFunction::CreateStaticVarDecl(const VarDecl &D, CGM.EmitNullConstant(D.getType()), Name, 0, D.isThreadSpecified(), Ty.getAddressSpace()); GV->setAlignment(getContext().getDeclAlign(&D).getQuantity()); + if (Linkage != llvm::GlobalValue::InternalLinkage) + GV->setVisibility(CurFn->getVisibility()); return GV; } @@ -209,8 +211,10 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(), OldGV->isConstant(), OldGV->getLinkage(), Init, "", - 0, D.isThreadSpecified(), + /*InsertBefore*/ OldGV, + D.isThreadSpecified(), D.getType().getAddressSpace()); + GV->setVisibility(OldGV->getVisibility()); // Steal the name of the old global GV->takeName(OldGV); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index d975a22643..a2b80bea6c 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1344,9 +1344,16 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) { Entry = NewFn; } + // We need to set linkage and visibility on the function before + // generating code for it because various parts of IR generation + // want to propagate this information down (e.g. to local static + // declarations). llvm::Function *Fn = cast(Entry); setFunctionLinkage(D, Fn); + // FIXME: this is redundant with part of SetFunctionDefinitionAttributes + setGlobalVisibility(Fn, D, /*ForDef*/ true); + CodeGenFunction(*this).GenerateCode(D, Fn); SetFunctionDefinitionAttributes(D, Fn); diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index b6c40b64db..94c1f60a8b 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -1092,6 +1092,9 @@ void ItaniumCXXABI::EmitStaticLocalInit(CodeGenFunction &CGF, // Create the guard variable. llvm::SmallString<256> GuardVName; getMangleContext().mangleItaniumGuardVariable(&D, GuardVName); + + // FIXME: we should just absorb linkage and visibility from the + // variable, but that's not always set up properly just yet. llvm::GlobalValue::LinkageTypes Linkage = GV->getLinkage(); if (D.isStaticDataMember() && D.getInstantiatedFromStaticDataMember()) @@ -1102,6 +1105,7 @@ void ItaniumCXXABI::EmitStaticLocalInit(CodeGenFunction &CGF, false, Linkage, llvm::ConstantInt::get(GuardTy, 0), GuardVName.str()); + GuardVariable->setVisibility(GV->getVisibility()); // Test whether the variable has completed initialization. llvm::Value *IsInitialized; diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp index c9febfbdfe..8d23da0a37 100644 --- a/test/CodeGenCXX/visibility.cpp +++ b/test/CodeGenCXX/visibility.cpp @@ -22,6 +22,10 @@ // CHECK-HIDDEN: @_ZN6Test143varE = external global // CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] // CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] +// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global +// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 +// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global +// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 // CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external constant // CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external constant // CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant @@ -339,3 +343,16 @@ namespace Test18 { // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() } + +namespace Test19 { + struct A { A(); ~A(); }; + + // Tested at top of file. + template void foo() { + static A a; + } + + void test() { + foo(); + } +} -- 2.40.0