r246864 - Don't allow dllexport/import on static local variables

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 4 12:59:39 PDT 2015


Author: hans
Date: Fri Sep  4 14:59:39 2015
New Revision: 246864

URL: http://llvm.org/viewvc/llvm-project?rev=246864&view=rev
Log:
Don't allow dllexport/import on static local variables

They might technically have external linkage, but it still doesn't make sense
for the user to try and export such variables. This matches MSVC's and MinGW's
behaviour.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/dllexport.c
    cfe/trunk/test/Sema/dllimport.c
    cfe/trunk/test/SemaCXX/dllexport.cpp
    cfe/trunk/test/SemaCXX/dllimport.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=246864&r1=246863&r2=246864&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Sep  4 14:59:39 2015
@@ -5355,9 +5355,11 @@ static void checkAttributesAfterMerging(
     }
   }
 
-  // dll attributes require external linkage.
   if (const InheritableAttr *Attr = getDLLAttr(&ND)) {
-    if (!ND.isExternallyVisible()) {
+    // dll attributes require external linkage. Static locals may have external
+    // linkage but still cannot be explicitly imported or exported.
+    auto *VD = dyn_cast<VarDecl>(&ND);
+    if (!ND.isExternallyVisible() || (VD && VD->isStaticLocal())) {
       S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern)
         << &ND << Attr;
       ND.setInvalidDecl();

Modified: cfe/trunk/test/Sema/dllexport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllexport.c?rev=246864&r1=246863&r2=246864&view=diff
==============================================================================
--- cfe/trunk/test/Sema/dllexport.c (original)
+++ cfe/trunk/test/Sema/dllexport.c Fri Sep  4 14:59:39 2015
@@ -109,6 +109,11 @@ __declspec(dllexport) void redecl6(); //
 // External linkage is required.
 __declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}}
 
+// Static locals don't count as having external linkage.
+void staticLocalFunc() {
+  __declspec(dllexport) static int staticLocal; // expected-error{{'staticLocal' must have external linkage when declared 'dllexport'}}
+}
+
 
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/Sema/dllimport.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/dllimport.c?rev=246864&r1=246863&r2=246864&view=diff
==============================================================================
--- cfe/trunk/test/Sema/dllimport.c (original)
+++ cfe/trunk/test/Sema/dllimport.c Fri Sep  4 14:59:39 2015
@@ -168,3 +168,8 @@ __declspec(dllimport) inline void redecl
 
 // External linkage is required.
 __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
+
+// Static locals don't count as having external linkage.
+void staticLocalFunc() {
+  __declspec(dllimport) static int staticLocal; // expected-error{{'staticLocal' must have external linkage when declared 'dllimport'}}
+}

Modified: cfe/trunk/test/SemaCXX/dllexport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllexport.cpp?rev=246864&r1=246863&r2=246864&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dllexport.cpp (original)
+++ cfe/trunk/test/SemaCXX/dllexport.cpp Fri Sep  4 14:59:39 2015
@@ -71,14 +71,9 @@ __declspec(dllexport) auto ExternalAutoT
 
 // Thread local variables are invalid.
 __declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}}
-inline void InlineWithThreadLocal() {
-  static __declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}}
-}
-
-// But if they're in a dllexport function, it's ok, because they will never get imported.
+// But a static local TLS var in an export function is OK.
 inline void __declspec(dllexport) ExportedInlineWithThreadLocal() {
-  static __declspec(dllexport) __thread int OK1; // no-error
-  static __thread int OK2; // no-error
+  static __thread int OK; // no-error
 }
 
 // Export in local scope.

Modified: cfe/trunk/test/SemaCXX/dllimport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/dllimport.cpp?rev=246864&r1=246863&r2=246864&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/dllimport.cpp (original)
+++ cfe/trunk/test/SemaCXX/dllimport.cpp Fri Sep  4 14:59:39 2015
@@ -93,16 +93,10 @@ __declspec(dllimport) auto InternalAutoT
 
 // Thread local variables are invalid.
 __declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}}
-inline void InlineWithThreadLocal() {
-  static __declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}}
-}
-
-// But if they're in a dllimported function, it's OK because we will not inline the function.
 // This doesn't work on MinGW, because there, dllimport on the inline function is ignored.
 #ifndef GNU
 inline void __declspec(dllimport) ImportedInlineWithThreadLocal() {
-  static __declspec(dllimport) __thread int OK1; // no-error
-  static __thread int OK2; // no-error
+  static __thread int OK; // no-error
 }
 #endif
 




More information about the cfe-commits mailing list