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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@246864
91177308-0d34-0410-b5e6-
96231b3b80d8
}
}
- // 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();
// 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'}}
+}
+
//===----------------------------------------------------------------------===//
// 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'}}
+}
// 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.
// 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