summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-06-11 04:08:55 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-06-11 04:08:55 +0000
commit35ab328e942259b6ebb75785f54abbfdf6f50d93 (patch)
treecc50a07928a9a2b04cbbff3a9aae354bfc8eca6e /clang/lib
parenta813d608a943579804eb9f12c8ede2955bb3a777 (diff)
downloadbcm5719-llvm-35ab328e942259b6ebb75785f54abbfdf6f50d93.tar.gz
bcm5719-llvm-35ab328e942259b6ebb75785f54abbfdf6f50d93.zip
CodeGen: Correct linkage of thread_local for OS X
The backing store of thread local variables is internal for OS X and all accesses must go through the thread wrapper. However, individual TUs may have inlined through the thread wrapper. To fix this, give the thread wrapper functions WeakAnyLinkage. This prevents them from getting inlined into call-sites. This fixes PR19989. llvm-svn: 210632
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp8
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp10
-rw-r--r--clang/lib/CodeGen/ItaniumCXXABI.cpp21
3 files changed, 25 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);
OpenPOWER on IntegriCloud