]> granicus.if.org Git - clang/commitdiff
MS ABI: Disallow dllimported/exported variables from having TLS
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 4 Oct 2014 06:51:54 +0000 (06:51 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 4 Oct 2014 06:51:54 +0000 (06:51 +0000)
Windows TLS relies on indexing through a tls_index in order to get at
the DLL's thread local variables.  However, this index is not exported
along with the variable: it is assumed that all accesses to thread local
variables are inside the same module which created the variable in the
first place.

While there are several implementation techniques we could adopt to fix
this (notably, the Itanium ABI gets this for free), it is not worth the
heroics.

Instead, let's just ban this combination.  We could revisit this in the
future if we need to.

This fixes PR21111.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219049 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/Sema/dllexport.c
test/Sema/dllimport.c
test/SemaCXX/dllexport.cpp
test/SemaCXX/dllimport.cpp

index 5fb3af619081851abd312a9a50c3200899adb004..7db98d59923a286987928cf664a5f7d49f0608c0 100644 (file)
@@ -2161,6 +2161,8 @@ def err_declspec_thread_on_thread_variable : Error<
   "thread-local storage specifier">;
 def err_attribute_dll_not_extern : Error<
   "%q0 must have external linkage when declared %q1">;
+def err_attribute_dll_thread_local : Error<
+  "%q0 cannot be thread local when declared %q1">;
 def warn_attribute_invalid_on_definition : Warning<
   "'%0' attribute cannot be specified on a definition">,
   InGroup<IgnoredAttributes>;
index 03dd2a7093cd8a1a9152efcbf68f390f9cd9692d..c3c436d8e310134a06237f7f39af53e79c2cc771 100644 (file)
@@ -9534,8 +9534,11 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
     }
   }
 
+  // Grab the dllimport or dllexport attribute off of the VarDecl.
+  const InheritableAttr *DLLAttr = getDLLAttr(VD);
+
   // Imported static data members cannot be defined out-of-line.
-  if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) {
+  if (const auto *IA = dyn_cast_or_null<DLLImportAttr>(DLLAttr)) {
     if (VD->isStaticDataMember() && VD->isOutOfLine() &&
         VD->isThisDeclarationADefinition()) {
       // We allow definitions of dllimport class template static data members
@@ -9556,6 +9559,14 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
     }
   }
 
+  // dllimport/dllexport variables cannot be thread local, their TLS index
+  // isn't exported with the variable.
+  if (DLLAttr && VD->getTLSKind()) {
+    Diag(VD->getLocation(), diag::err_attribute_dll_thread_local) << VD
+                                                                  << DLLAttr;
+    VD->setInvalidDecl();
+  }
+
   if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) {
     if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) {
       Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr;
index 6c71ad82987b1581946d5c866bd04c02d5c03a7e..76b6f6dc5a0e3ef57c27587081ceeb2455e5579b 100644 (file)
@@ -49,6 +49,9 @@ __declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclarati
 // External linkage is required.
 __declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}}
 
+// Thread local variables are invalid.
+__declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}}
+
 // Export in local scope.
 void functionScope() {
   __declspec(dllexport)        int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
index d64c85953d0a3b19f5e477623fedcbdbc918f9cc..1b111077b623b31cf2df88a0b4b6d131930b6f07 100644 (file)
@@ -77,6 +77,9 @@ __declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclarati
 // External linkage is required.
 __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
 
+// Thread local variables are invalid.
+__declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}}
+
 // Import in local scope.
 __declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}}
 __declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}}
index df87c7378656b64412ed9dbf5e845b078045d212..5d6889440951b6a58e90a968e0ea74cfc0989e2f 100644 (file)
@@ -64,6 +64,9 @@ namespace ns { __declspec(dllexport) int ExternalGlobal; }
 __declspec(dllexport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllexport'}}
 __declspec(dllexport) auto ExternalAutoTypeGlobal = External();
 
+// Thread local variables are invalid.
+__declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}}
+
 // Export in local scope.
 void functionScope() {
   __declspec(dllexport)        int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}}
index d0e88368fc391b9f0606189b346f815707574f5e..1ba25dbbc5c32380c3738e963aae64a428ce00c0 100644 (file)
@@ -86,6 +86,9 @@ namespace ns { __declspec(dllimport) int ExternalGlobal; }
 __declspec(dllimport) auto InternalAutoTypeGlobal = Internal(); // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}
                                                                 // expected-error@-1{{definition of dllimport data}}
 
+// Thread local variables are invalid.
+__declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}}
+
 // Import in local scope.
 __declspec(dllimport) float LocalRedecl1; // expected-note{{previous definition is here}}
 __declspec(dllimport) float LocalRedecl2; // expected-note{{previous definition is here}}