CodeGen support for function-local static thread_local variables with
non-constant constructors or non-trivial destructors. Plus bugfixes for
thread_local references bound to temporaries (the temporaries themselves are
lifetime-extended to become thread_local), and the corresponding case for
std::initializer_list.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179496 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index c515508..1c06b7d 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -184,12 +184,16 @@
       llvm::Type *RefTempTy = CGF.ConvertTypeForMem(Type);
   
       // Create the reference temporary.
-      llvm::GlobalValue *RefTemp =
+      llvm::GlobalVariable *RefTemp =
         new llvm::GlobalVariable(CGF.CGM.getModule(), 
                                  RefTempTy, /*isConstant=*/false,
                                  llvm::GlobalValue::InternalLinkage,
                                  llvm::Constant::getNullValue(RefTempTy),
                                  Name.str());
+      // If we're binding to a thread_local variable, the temporary is also
+      // thread local.
+      if (VD->getTLSKind())
+        CGF.CGM.setTLSMode(RefTemp, *VD);
       return RefTemp;
     }
   }
@@ -434,12 +438,15 @@
           CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete);
         CleanupArg = cast<llvm::Constant>(ReferenceTemporary);
       }
-      CGM.getCXXABI().registerGlobalDtor(*this, CleanupFn, CleanupArg);
+      CGM.getCXXABI().registerGlobalDtor(*this, *VD, CleanupFn, CleanupArg);
     } else if (ReferenceInitializerList) {
+      // FIXME: This is wrong. We need to register a global destructor to clean
+      // up the initializer_list object, rather than adding it as a local
+      // cleanup.
       EmitStdInitializerListCleanup(ReferenceTemporary,
                                     ReferenceInitializerList);
     } else {
-      assert(!ObjCARCReferenceLifetimeType.isNull());
+      assert(!ObjCARCReferenceLifetimeType.isNull() && !VD->getTLSKind());
       // Note: We intentionally do not register a global "destructor" to
       // release the object.
     }