From 496524b4484bce312c7885dab25846e69498727f Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Sat, 31 May 2014 02:08:49 +0000 Subject: [PATCH] Diagnose dll attribute on member of class that already has a dll attribute Differential Revision: http://reviews.llvm.org/D3973 llvm-svn: 209954 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/Sema/SemaDeclCXX.cpp | 23 ++++++++++++++------- clang/test/SemaCXX/dllimport.cpp | 26 ++++++++++++++++++++++-- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 758bf23..da011e4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 48c2c5d..8a40a2e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -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(Member) && !isa(Member)) continue; - auto *NewAttr = cast(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(ClassAttr->clone(S.getASTContext())); + NewAttr->setInherited(true); + Member->addAttr(NewAttr); + } if (CXXMethodDecl *MD = dyn_cast(Member)) { if (ClassExported) { diff --git a/clang/test/SemaCXX/dllimport.cpp b/clang/test/SemaCXX/dllimport.cpp index 8f7eb5b..3f4a487 100644 --- a/clang/test/SemaCXX/dllimport.cpp +++ b/clang/test/SemaCXX/dllimport.cpp @@ -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 template __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(); +}; -- 2.7.4