Don't allow dllimport/export on classes with internal linkage (PR21399)
authorHans Wennborg <hans@hanshq.net>
Mon, 3 Nov 2014 16:09:16 +0000 (16:09 +0000)
committerHans Wennborg <hans@hanshq.net>
Mon, 3 Nov 2014 16:09:16 +0000 (16:09 +0000)
Trying to import or export such classes doesn't make sense, and Clang
would assert trying to export vtables for them.

This is consistent with how we treat functions with internal linkage,
but it is stricter than MSVC so we may have to back down if it breaks
real code.

llvm-svn: 221160

clang/lib/Sema/SemaDeclCXX.cpp
clang/test/SemaCXX/dllexport.cpp
clang/test/SemaCXX/dllimport.cpp

index 031edf1..0fae8c8 100644 (file)
@@ -4633,6 +4633,12 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
   if (!ClassAttr)
     return;
 
+  if (!Class->isExternallyVisible()) {
+    S.Diag(Class->getLocation(), diag::err_attribute_dll_not_extern)
+        << Class << ClassAttr;
+    return;
+  }
+
   if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
       !ClassAttr->isInherited()) {
     // Diagnose dll attributes on members of class with dll attribute.
index e6fc91d..5d002ac 100644 (file)
@@ -327,6 +327,10 @@ template<> __declspec(dllexport) inline void funcTmpl<ExplicitSpec_InlineDef_Exp
 // Classes
 //===----------------------------------------------------------------------===//
 
+namespace {
+  struct __declspec(dllexport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllexport'}}
+}
+
 class __declspec(dllexport) ClassDecl;
 
 class __declspec(dllexport) ClassDef {};
index 50d952e..eb6a554 100644 (file)
@@ -1197,6 +1197,10 @@ template<typename T> template<typename U> __declspec(dllimport) constexpr int CT
 // Classes
 //===----------------------------------------------------------------------===//
 
+namespace {
+  struct __declspec(dllimport) AnonymousClass {}; // expected-error{{(anonymous namespace)::AnonymousClass' must have external linkage when declared 'dllimport'}}
+}
+
 class __declspec(dllimport) ClassDecl;
 
 class __declspec(dllimport) ClassDef { };