aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGCXX.cpp2
-rw-r--r--lib/CodeGen/CGDecl.cpp16
-rw-r--r--lib/CodeGen/CGVTables.cpp2
-rw-r--r--lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--lib/CodeGen/CodeGenModule.h4
-rw-r--r--test/CodeGenCXX/static-init.cpp15
6 files changed, 29 insertions, 12 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 74cf1134d5..85222fe9db 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -206,6 +206,7 @@ void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D,
return;
llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXConstructor(D, Type));
+ setFunctionLinkage(D, Fn);
CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
@@ -269,6 +270,7 @@ void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D,
return;
llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXDestructor(D, Type));
+ setFunctionLinkage(D, Fn);
CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 611ebed5a3..8115e384db 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -114,14 +114,14 @@ void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
llvm::GlobalValue::LinkageTypes Linkage =
llvm::GlobalValue::InternalLinkage;
- // If this is a static declaration inside an inline function, it must have
- // weak linkage so that the linker will merge multiple definitions of it.
- if (getContext().getLangOptions().CPlusPlus) {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) {
- if (FD->isInlined())
- Linkage = llvm::GlobalValue::WeakAnyLinkage;
- }
- }
+ // If the function definition has some sort of weak linkage, its
+ // static variables should also be weak so that they get properly
+ // uniqued. We can't do this in C, though, because there's no
+ // standard way to agree on which variables are the same (i.e.
+ // there's no mangling).
+ if (getContext().getLangOptions().CPlusPlus)
+ if (llvm::GlobalValue::isWeakForLinker(CurFn->getLinkage()))
+ Linkage = CurFn->getLinkage();
return EmitStaticBlockVarDecl(D, Linkage);
}
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index b66b9f8493..8bdd4588d4 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -2723,7 +2723,7 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD,
CXXThisDecl->Destroy(getContext());
// Set the right linkage.
- Fn->setLinkage(CGM.getFunctionLinkage(MD));
+ CGM.setFunctionLinkage(MD, Fn);
// Set the right visibility.
CGM.setGlobalVisibility(Fn, MD);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 05c7a87e5f..2f8404e251 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -361,7 +361,6 @@ CodeGenModule::getFunctionLinkage(const FunctionDecl *D) {
/// variables (these details are set in EmitGlobalVarDefinition for variables).
void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
llvm::GlobalValue *GV) {
- GV->setLinkage(getFunctionLinkage(D));
SetCommonAttributes(D, GV);
}
@@ -1330,6 +1329,7 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
}
llvm::Function *Fn = cast<llvm::Function>(Entry);
+ setFunctionLinkage(D, Fn);
CodeGenFunction(*this).GenerateCode(D, Fn);
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 0e4f4a932e..e225462fac 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -436,6 +436,10 @@ public:
llvm::GlobalVariable::LinkageTypes
getFunctionLinkage(const FunctionDecl *FD);
+ void setFunctionLinkage(const FunctionDecl *FD, llvm::GlobalValue *V) {
+ V->setLinkage(getFunctionLinkage(FD));
+ }
+
/// getVTableLinkage - Return the appropriate linkage for the vtable, VTT,
/// and type information of the given class.
static llvm::GlobalVariable::LinkageTypes
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index f9604d9643..9ad87df8f0 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -2,8 +2,9 @@
// CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
-// CHECK: @_ZZ2h2vE1i = weak global i32 0
-// CHECK: @_ZGVZ2h2vE1i = weak global i64 0
+// CHECK: @_ZZN5test16getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 4
+// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
+// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
struct A {
A();
@@ -47,3 +48,13 @@ namespace test0 {
static A r;
}
}
+
+namespace test1 {
+ // CHECK: define internal i32 @_ZN5test16getvarEi(
+ static inline int getvar(int index) {
+ static const int var[] = { 1, 0, 2, 4 };
+ return var[index];
+ }
+
+ void test() { (void) getvar(2); }
+}