From: David Majnemer Date: Wed, 15 Oct 2014 22:38:23 +0000 (+0000) Subject: CodeGen: Don't drop thread_local when emitting __thread aliases X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ceb95abd7dc1a367632544b7f70d9a1b642a57d0;p=clang CodeGen: Don't drop thread_local when emitting __thread aliases CodeGen wouldn't mark the aliasee as thread_local if the aliasee was a tentative definition. Even if the definition was already emitted, it would never mark the alias as thread_local. This fixes PR21288. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219859 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index f8db0eeaf8..7d8c34d199 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -523,11 +523,10 @@ static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel( llvm_unreachable("Invalid TLS model!"); } -void CodeGenModule::setTLSMode(llvm::GlobalVariable *GV, - const VarDecl &D) const { +void CodeGenModule::setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const { assert(D.getTLSKind() && "setting TLS mode on non-TLS var!"); - llvm::GlobalVariable::ThreadLocalMode TLM; + llvm::GlobalValue::ThreadLocalMode TLM; TLM = GetLLVMTLSModel(CodeGenOpts.getDefaultTLSModel()); // Override the TLS model if it is explicitly specified. @@ -1942,10 +1941,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { // 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(D)) - if (!VD->isStaticLocal() && VD->getTLSKind() == VarDecl::TLS_Dynamic && - Context.getTargetInfo().getTriple().isMacOSX()) - Linkage = llvm::GlobalValue::InternalLinkage; + if (!D->isStaticLocal() && D->getTLSKind() == VarDecl::TLS_Dynamic && + Context.getTargetInfo().getTriple().isMacOSX()) + Linkage = llvm::GlobalValue::InternalLinkage; GV->setLinkage(Linkage); if (D->hasAttr()) @@ -1959,6 +1957,12 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { setNonAliasAttributes(D, GV); + if (D->getTLSKind() && !GV->isThreadLocal()) { + if (D->getTLSKind() == VarDecl::TLS_Dynamic) + CXXThreadLocals.push_back(std::make_pair(D, GV)); + setTLSMode(GV, *D); + } + // Emit the initializer function if necessary. if (NeedsGlobalCtor || NeedsGlobalDtor) EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor); @@ -2326,7 +2330,7 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { else Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), llvm::PointerType::getUnqual(DeclTy), - nullptr); + /*D=*/nullptr); // Create the new alias itself, but don't set a name yet. auto *GA = llvm::GlobalAlias::create( @@ -2365,6 +2369,10 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { GA->setLinkage(llvm::Function::WeakAnyLinkage); } + if (const auto *VD = dyn_cast(D)) + if (VD->getTLSKind()) + setTLSMode(GA, *VD); + setAliasAttributes(D, GA); } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index c5c9d6eccc..a63b799baa 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -652,9 +652,9 @@ public: /// Set the visibility for the given LLVM GlobalValue. void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const; - /// Set the TLS mode for the given LLVM GlobalVariable for the thread-local + /// Set the TLS mode for the given LLVM GlobalValue for the thread-local /// variable declaration D. - void setTLSMode(llvm::GlobalVariable *GV, const VarDecl &D) const; + void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const; static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) { switch (V) { diff --git a/test/CodeGen/alias.c b/test/CodeGen/alias.c index faed487a40..b773cc8de9 100644 --- a/test/CodeGen/alias.c +++ b/test/CodeGen/alias.c @@ -3,6 +3,8 @@ int g0; // CHECKBASIC: @g0 = common global i32 0 +__thread int TL_WITH_ALIAS; +// CHECKBASIC-DAG: @TL_WITH_ALIAS = thread_local global i32 0, align 4 static int bar1 = 42; // CHECKBASIC: @bar1 = internal global i32 42 @@ -10,6 +12,9 @@ extern int g1; extern int g1 __attribute((alias("g0"))); // CHECKBASIC-DAG: @g1 = alias i32* @g0 +extern __thread int __libc_errno __attribute__ ((alias ("TL_WITH_ALIAS"))); +// CHECKBASIC-DAG: @__libc_errno = thread_local alias i32* @TL_WITH_ALIAS + void f0(void) { } extern void f1(void); extern void f1(void) __attribute((alias("f0")));