diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 13 | ||||
-rw-r--r-- | clang/test/Sema/dllexport.c | 3 | ||||
-rw-r--r-- | clang/test/Sema/dllimport.c | 3 | ||||
-rw-r--r-- | clang/test/SemaCXX/dllexport.cpp | 3 | ||||
-rw-r--r-- | clang/test/SemaCXX/dllimport.cpp | 3 |
6 files changed, 26 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5fb3af61908..7db98d59923 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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>; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 03dd2a7093c..c3c436d8e31 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -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; diff --git a/clang/test/Sema/dllexport.c b/clang/test/Sema/dllexport.c index 6c71ad82987..76b6f6dc5a0 100644 --- a/clang/test/Sema/dllexport.c +++ b/clang/test/Sema/dllexport.c @@ -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'}} diff --git a/clang/test/Sema/dllimport.c b/clang/test/Sema/dllimport.c index d64c85953d0..1b111077b62 100644 --- a/clang/test/Sema/dllimport.c +++ b/clang/test/Sema/dllimport.c @@ -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}} diff --git a/clang/test/SemaCXX/dllexport.cpp b/clang/test/SemaCXX/dllexport.cpp index df87c737865..5d688944095 100644 --- a/clang/test/SemaCXX/dllexport.cpp +++ b/clang/test/SemaCXX/dllexport.cpp @@ -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'}} diff --git a/clang/test/SemaCXX/dllimport.cpp b/clang/test/SemaCXX/dllimport.cpp index d0e88368fc3..1ba25dbbc5c 100644 --- a/clang/test/SemaCXX/dllimport.cpp +++ b/clang/test/SemaCXX/dllimport.cpp @@ -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}} |