Index: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp @@ -235,7 +235,7 @@ llvm::Constant *dtor, llvm::Constant *addr) override; llvm::Function *getOrCreateThreadLocalWrapper(const VarDecl *VD, - llvm::GlobalVariable *Var); + llvm::Value *Val); void EmitThreadLocalInitFuncs( ArrayRef > Decls, llvm::Function *InitFunc) override; @@ -1870,7 +1870,7 @@ llvm::Function * ItaniumCXXABI::getOrCreateThreadLocalWrapper(const VarDecl *VD, - llvm::GlobalVariable *Var) { + llvm::Value *Val) { // Mangle the name for the thread_local wrapper function. SmallString<256> WrapperName; { @@ -1879,10 +1879,10 @@ Out.flush(); } - if (llvm::Value *V = Var->getParent()->getNamedValue(WrapperName)) + if (llvm::Value *V = CGM.getModule().getNamedValue(WrapperName)) return cast(V); - llvm::Type *RetTy = Var->getType(); + llvm::Type *RetTy = Val->getType(); if (VD->getType()->isReferenceType()) RetTy = RetTy->getPointerElementType(); @@ -1970,7 +1970,9 @@ LI->setAlignment(CGM.getContext().getDeclAlign(VD).getQuantity()); Val = LI; } - + if (Val->getType() != Wrapper->getReturnType()) + Val = Builder.CreatePointerBitCastOrAddrSpaceCast( + Val, Wrapper->getReturnType(), ""); Builder.CreateRet(Val); } } @@ -1981,8 +1983,7 @@ QualType T = VD->getType(); llvm::Type *Ty = CGF.getTypes().ConvertTypeForMem(T); llvm::Value *Val = CGF.CGM.GetAddrOfGlobalVar(VD, Ty); - llvm::Function *Wrapper = - getOrCreateThreadLocalWrapper(VD, cast(Val)); + llvm::Function *Wrapper = getOrCreateThreadLocalWrapper(VD, Val); Val = CGF.Builder.CreateCall(Wrapper); Index: cfe/trunk/test/CodeGenCXX/pr18635.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/pr18635.cpp +++ cfe/trunk/test/CodeGenCXX/pr18635.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm -std=c++11 -triple x86_64-pc-linux-gnu -o- %s | FileCheck %s + +// Global @x: +// CHECK: [[X_GLOBAL:@[^ ]+]]{{.*}}thread_local global + +// returned somewhere in TLS wrapper: +// CHECK: ret{{.*}}[[X_GLOBAL]] + +template class unique_ptr { + template struct pair { + F first; + S second; + }; + pair data; +public: + constexpr unique_ptr() noexcept : data() {} + explicit unique_ptr(T *p) noexcept : data() {} +}; + +thread_local unique_ptr x; +int main() { x = unique_ptr(new int(5)); } +