[PATCH] Error on using dll attribute on members of class that already has a dll attribute

Hans Wennborg hans at chromium.org
Fri May 30 16:03:03 PDT 2014


Hi nrieck, rnk,

http://reviews.llvm.org/D3973

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

Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2109,6 +2109,8 @@
   "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<
@@ -2450,6 +2452,7 @@
   InGroup<DiagGroup<"unsupported-visibility">>;
 def err_mismatched_visibility: Error<"visibility does not match previous declaration">;
 def note_previous_attribute : Note<"previous attribute is here">;
+def note_class_attribute : Note<"class attribute is here">;
 def note_attribute : Note<"attribute is here">;
 def err_mismatched_ms_inheritance : Error<
   "inheritance model does not match %select{definition|previous declaration}0">;
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -4377,16 +4377,24 @@
   // 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 (!MemberAttr->isInherited()) {
+        S.Diag(MemberAttr->getLocation(),
+               diag::err_attribute_dll_member_of_dll_class)
+            << MemberAttr << ClassAttr;
+        S.Diag(ClassAttr->getLocation(), diag::note_class_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: test/SemaCXX/dllimport.cpp
===================================================================
--- test/SemaCXX/dllimport.cpp
+++ test/SemaCXX/dllimport.cpp
@@ -954,3 +954,13 @@
 class __declspec(dllimport) ClassDecl;
 
 class __declspec(dllimport) ClassDef { };
+
+class __declspec(dllimport) ImportClassWithDllMember { // expected-note2{{class attribute is here}}
+  void __declspec(dllexport) foo(); // expected-error{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}}
+  void __declspec(dllimport) bar(); // expected-error{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}}
+};
+
+class __declspec(dllexport) ExportClassWithDllMember { // expected-note2{{class attribute is here}}
+  void __declspec(dllimport) foo(); // expected-error{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}}
+  void __declspec(dllexport) bar(); // expected-error{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}}
+};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3973.9969.patch
Type: text/x-patch
Size: 3370 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140530/3290c28b/attachment.bin>


More information about the cfe-commits mailing list