summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/AST/ASTContext.cpp8
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp21
-rw-r--r--clang/test/CodeGenCXX/tls-init-funcs.cpp1
4 files changed, 26 insertions, 14 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index eaf77e96254..ddde907522b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7843,14 +7843,6 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
: StaticLocalLinkage;
}
- // On Darwin, the backing variable for a C++11 thread_local variable always
- // has internal linkage; all accesses should just be calls to the
- // Itanium-specified entry point, which has the normal linkage of the
- // variable.
- if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
- Context.getTargetInfo().getTriple().isMacOSX())
- return GVA_Internal;
-
switch (VD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b2d87db4880..79338787966 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1903,6 +1903,16 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
// Set the llvm linkage type as appropriate.
llvm::GlobalValue::LinkageTypes Linkage =
getLLVMLinkageVarDefinition(D, GV->isConstant());
+
+ // On Darwin, the backing variable for a C++11 thread_local variable always
+ // has internal linkage; all accesses should just be calls to the
+ // Itanium-specified entry point, which has the normal linkage of the
+ // variable.
+ if (const auto *VD = dyn_cast<VarDecl>(D))
+ if (!VD->isStaticLocal() && VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+ Context.getTargetInfo().getTriple().isMacOSX())
+ Linkage = llvm::GlobalValue::InternalLinkage;
+
GV->setLinkage(Linkage);
if (D->hasAttr<DLLImportAttr>())
GV->setDLLStorageClass(llvm::GlobalVariable::DLLImportStorageClass);
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 86eb36d8653..be8dac140ed 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1575,11 +1575,21 @@ void ItaniumCXXABI::registerGlobalDtor(CodeGenFunction &CGF,
/// Get the appropriate linkage for the wrapper function. This is essentially
/// the weak form of the variable's linkage; every translation unit which wneeds
/// the wrapper emits a copy, and we want the linker to merge them.
-static llvm::GlobalValue::LinkageTypes getThreadLocalWrapperLinkage(
- llvm::GlobalValue::LinkageTypes VarLinkage) {
+static llvm::GlobalValue::LinkageTypes
+getThreadLocalWrapperLinkage(const VarDecl *VD, CodeGen::CodeGenModule &CGM) {
+ llvm::GlobalValue::LinkageTypes VarLinkage =
+ CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false);
+
// For internal linkage variables, we don't need an external or weak wrapper.
if (llvm::GlobalValue::isLocalLinkage(VarLinkage))
return VarLinkage;
+
+ // All accesses to the thread_local variable go through the thread wrapper.
+ // However, this means that we cannot allow the thread wrapper to get inlined
+ // into any functions.
+ if (VD->getTLSKind() == VarDecl::TLS_Dynamic &&
+ CGM.getTarget().getTriple().isMacOSX())
+ return llvm::GlobalValue::WeakAnyLinkage;
return llvm::GlobalValue::WeakODRLinkage;
}
@@ -1602,10 +1612,9 @@ ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD,
RetTy = RetTy->getPointerElementType();
llvm::FunctionType *FnTy = llvm::FunctionType::get(RetTy, false);
- llvm::Function *Wrapper = llvm::Function::Create(
- FnTy, getThreadLocalWrapperLinkage(
- CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false)),
- WrapperName.str(), &CGM.getModule());
+ llvm::Function *Wrapper =
+ llvm::Function::Create(FnTy, getThreadLocalWrapperLinkage(VD, CGM),
+ WrapperName.str(), &CGM.getModule());
// Always resolve references to the wrapper at link time.
if (!Wrapper->hasLocalLinkage())
Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
diff --git a/clang/test/CodeGenCXX/tls-init-funcs.cpp b/clang/test/CodeGenCXX/tls-init-funcs.cpp
index 17299dcb7b6..99fe75f7f4f 100644
--- a/clang/test/CodeGenCXX/tls-init-funcs.cpp
+++ b/clang/test/CodeGenCXX/tls-init-funcs.cpp
@@ -2,6 +2,7 @@
// CHECK: @a = internal thread_local global
// CHECK: @_tlv_atexit({{.*}}@_ZN1AD1Ev
+// CHECK: define weak hidden {{.*}} @_ZTW1a
struct A {
~A();
OpenPOWER on IntegriCloud