]> granicus.if.org Git - clang/commitdiff
Diagnose dll attribute on member of class that already has a dll attribute
authorHans Wennborg <hans@hanshq.net>
Sat, 31 May 2014 02:08:49 +0000 (02:08 +0000)
committerHans Wennborg <hans@hanshq.net>
Sat, 31 May 2014 02:08:49 +0000 (02:08 +0000)
Differential Revision: http://reviews.llvm.org/D3973

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/dllimport.cpp

index 758bf23c30d4905cb7b02532fb1be2e935a4c3ce..da011e461544722376573cf2ed212a65d0af48cd 100644 (file)
@@ -2109,6 +2109,8 @@ def err_attribute_dllimport_data_definition : Error<
   "definition of dllimport data">;
 def err_attribute_dllimport_static_field_definition : Error<
   "definition of dllimport static field not allowed">;
+def err_attribute_dll_member_of_dll_class : Error<
+  "attribute %q0 cannot be applied to member of %q1 class">;
 def err_attribute_weakref_not_static : Error<
   "weakref declaration must have internal linkage">;
 def err_attribute_weakref_not_global_context : Error<
index 48c2c5d3559e45ffdd9a656497912216d3402bfa..8a40a2e15a87425cd2aea4892ce385b34282c0c1 100644 (file)
@@ -4377,16 +4377,25 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
   // specialization bases.
 
   for (Decl *Member : Class->decls()) {
-    if (getDLLAttr(Member)) {
-      // FIXME: Error about importing/exporting individual members.
-    }
-
     if (!isa<CXXMethodDecl>(Member) && !isa<VarDecl>(Member))
       continue;
 
-    auto *NewAttr = cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
-    NewAttr->setInherited(true);
-    Member->addAttr(NewAttr);
+    if (InheritableAttr *MemberAttr = getDLLAttr(Member)) {
+      if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+          !MemberAttr->isInherited()) {
+        S.Diag(MemberAttr->getLocation(),
+               diag::err_attribute_dll_member_of_dll_class)
+            << MemberAttr << ClassAttr;
+        S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute);
+        Member->setInvalidDecl();
+        continue;
+      }
+    } else {
+      auto *NewAttr =
+          cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
+      NewAttr->setInherited(true);
+      Member->addAttr(NewAttr);
+    }
 
     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member)) {
       if (ClassExported) {
index 8f7eb5bc4b26d07fdb0623d0a95b1e504ab2aa7b..3f4a4871c529a27f6c80eb84095c4b3156dd8e94 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 %s
-// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 -DMS %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y -DMS %s
 // RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c++1y %s
 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
 
@@ -954,3 +954,25 @@ template<typename T> template<typename U> __declspec(dllimport) constexpr int CT
 class __declspec(dllimport) ClassDecl;
 
 class __declspec(dllimport) ClassDef { };
+
+#ifdef MS
+// expected-note@+5{{previous attribute is here}}
+// expected-note@+4{{previous attribute is here}}
+// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}}
+// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}}
+#endif
+class __declspec(dllimport) ImportClassWithDllMember {
+  void __declspec(dllexport) foo();
+  void __declspec(dllimport) bar();
+};
+
+#ifdef MS
+// expected-note@+5{{previous attribute is here}}
+// expected-note@+4{{previous attribute is here}}
+// expected-error@+4{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}}
+// expected-error@+4{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}}
+#endif
+class __declspec(dllexport) ExportClassWithDllMember {
+  void __declspec(dllimport) foo();
+  void __declspec(dllexport) bar();
+};