Summary:
Teach clang to mark thread wrappers for thread_local variables with
hidden visibility when the original variable is marked with hidden
visibility. This is necessary on Darwin which exposes the thread wrapper
instead of the thread variable. The thread wrapper would previously
always be created with default visibility unless it had
linkonce*/weak_odr linkage.
Reviewers: rjmccall
Reviewed By: rjmccall
Differential Revision: https://reviews.llvm.org/D56818
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@351457
91177308-0d34-0410-b5e6-
96231b3b80d8
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Wrapper);
// Always resolve references to the wrapper at link time.
- if (!Wrapper->hasLocalLinkage() && !(isThreadWrapperReplaceable(VD, CGM) &&
- !llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) &&
- !llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage())))
- Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
+ if (!Wrapper->hasLocalLinkage())
+ if (!isThreadWrapperReplaceable(VD, CGM) ||
+ llvm::GlobalVariable::isLinkOnceLinkage(Wrapper->getLinkage()) ||
+ llvm::GlobalVariable::isWeakODRLinkage(Wrapper->getLinkage()) ||
+ VD->getVisibility() == HiddenVisibility)
+ Wrapper->setVisibility(llvm::GlobalValue::HiddenVisibility);
if (isThreadWrapperReplaceable(VD, CGM)) {
Wrapper->setCallingConv(llvm::CallingConv::CXX_FAST_TLS);
--- /dev/null
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck --check-prefix=LINUX %s
+// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple x86_64-apple-darwin12 | FileCheck --check-prefix=DARWIN %s
+
+// Regression test for PR40327
+
+// LINUX: @default_tls = thread_local global i32
+// LINUX: @hidden_tls = hidden thread_local global i32
+// LINUX: define weak_odr hidden i32* @_ZTW11default_tls()
+// LINUX: define weak_odr hidden i32* @_ZTW10hidden_tls()
+//
+// DARWIN: @default_tls = internal thread_local global i32
+// DARWIN: @hidden_tls = internal thread_local global i32
+// DARWIN: define cxx_fast_tlscc i32* @_ZTW11default_tls()
+// DARWIN: define hidden cxx_fast_tlscc i32* @_ZTW10hidden_tls()
+
+__attribute__((visibility("default"))) thread_local int default_tls;
+__attribute__((visibility("hidden"))) thread_local int hidden_tls;
// CHECK-NOT: call void @[[V_M_INIT]]()
-// LIUNX: define weak_odr hidden i32* @_ZTW1a() {
+// LINUX: define weak_odr hidden i32* @_ZTW1a()
// DARWIN: define cxx_fast_tlscc i32* @_ZTW1a()
// LINUX: call void @_ZTH1a()
// DARWIN: call cxx_fast_tlscc void @_ZTH1a()