summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-08-24 00:12:36 +0000
committerHans Wennborg <hans@hanshq.net>2014-08-24 00:12:36 +0000
commitc2b7f7a6ab63755ee366bd4b2e334e895a8fc5ab (patch)
tree4eab11e51e03ef8e19b81f6b1bc69bca575e7dd2 /clang/lib/Sema/SemaDeclCXX.cpp
parent584a70c820a543ad98288f3a184cae0c4f290bd0 (diff)
downloadbcm5719-llvm-c2b7f7a6ab63755ee366bd4b2e334e895a8fc5ab.tar.gz
bcm5719-llvm-c2b7f7a6ab63755ee366bd4b2e334e895a8fc5ab.zip
Don't assert on different DLL attributes in template and explicit instantiation (PR20137)
We would previously assert (a decl cannot have two DLL attributes) on this code: template <typename T> struct __declspec(dllimport) S { T f() { return T(); } }; template struct __declspec(dllexport) S<int>; The problem was that when instantiating, we would take the attribute from the template even if the instantiation itself already had an attribute. Also, don't inherit DLL attributes from the template to its members before instantiation, as the attribute may change. I couldn't figure out what MinGW does here, so I'm leaving that open. At least we're not asserting anymore. llvm-svn: 216340
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp34
1 files changed, 23 insertions, 11 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5e789fe20ed..6a48162502c 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -4437,6 +4437,28 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
if (!ClassAttr)
return;
+ if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ !ClassAttr->isInherited()) {
+ // Diagnose dll attributes on members of class with dll attribute.
+ for (Decl *Member : Class->decls()) {
+ if (!isa<VarDecl>(Member) && !isa<CXXMethodDecl>(Member))
+ continue;
+ InheritableAttr *MemberAttr = getDLLAttr(Member);
+ if (!MemberAttr || MemberAttr->isInherited() || Member->isInvalidDecl())
+ continue;
+
+ S.Diag(MemberAttr->getLocation(),
+ diag::err_attribute_dll_member_of_dll_class)
+ << MemberAttr << ClassAttr;
+ S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute);
+ Member->setInvalidDecl();
+ }
+ }
+
+ if (Class->getDescribedClassTemplate())
+ // Don't inherit dll attribute until the template is instantiated.
+ return;
+
bool ClassExported = ClassAttr->getKind() == attr::DLLExport;
// Force declaration of implicit members so they can inherit the attribute.
@@ -4467,17 +4489,7 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) {
continue;
}
- if (InheritableAttr *MemberAttr = getDLLAttr(Member)) {
- if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- !MemberAttr->isInherited() && !ClassAttr->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 {
+ if (!getDLLAttr(Member)) {
auto *NewAttr =
cast<InheritableAttr>(ClassAttr->clone(S.getASTContext()));
NewAttr->setInherited(true);
OpenPOWER on IntegriCloud