diff options
author | Hans Wennborg <hans@hanshq.net> | 2015-01-15 21:18:30 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2015-01-15 21:18:30 +0000 |
commit | fd76d91366016494ef1915ae9481d81ed61d339d (patch) | |
tree | 7ce3bda05b3757be60d8c0dd8c3ec6a412203bbd /clang/lib | |
parent | e2ab0f17cf322b4384186ad392b1ea9abbbc23c4 (diff) | |
download | bcm5719-llvm-fd76d91366016494ef1915ae9481d81ed61d339d.tar.gz bcm5719-llvm-fd76d91366016494ef1915ae9481d81ed61d339d.zip |
Warn about dllexported explicit class template instantiation declarations (PR22035)
Clang would previously become confused and crash here.
It does not make a lot of sense to export these, so warning seems appropriate.
MSVC will export some member functions for this kind of specializations, whereas
MinGW ignores the dllexport-edness. The latter behaviour seems better.
Differential Revision: http://reviews.llvm.org/D6984
llvm-svn: 226208
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 24 |
2 files changed, 29 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 54de4b97939..79529d5547e 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4709,15 +4709,20 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { const bool ClassExported = ClassAttr->getKind() == attr::DLLExport; const bool ClassImported = !ClassExported; + TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind(); + + // Don't dllexport explicit class template instantiation declarations. + if (ClassExported && TSK == TSK_ExplicitInstantiationDeclaration) { + Class->dropAttr<DLLExportAttr>(); + return; + } + // Force declaration of implicit members so they can inherit the attribute. S.ForceDeclarationOfImplicitMembers(Class); // FIXME: MSVC's docs say all bases must be exportable, but this doesn't // seem to be true in practice? - TemplateSpecializationKind TSK = - Class->getTemplateSpecializationKind(); - for (Decl *Member : Class->decls()) { VarDecl *VD = dyn_cast<VarDecl>(Member); CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 67c36a5fb5e..254e78fa017 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -7165,9 +7165,27 @@ Sema::ActOnExplicitInstantiation(Scope *S, // There are two forms of explicit instantiation: an explicit instantiation // definition and an explicit instantiation declaration. An explicit // instantiation declaration begins with the extern keyword. [...] - TemplateSpecializationKind TSK - = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition - : TSK_ExplicitInstantiationDeclaration; + TemplateSpecializationKind TSK = ExternLoc.isInvalid() + ? TSK_ExplicitInstantiationDefinition + : TSK_ExplicitInstantiationDeclaration; + + if (TSK == TSK_ExplicitInstantiationDeclaration) { + // Check for dllexport class template instantiation declarations. + for (AttributeList *A = Attr; A; A = A->getNext()) { + if (A->getKind() == AttributeList::AT_DLLExport) { + Diag(ExternLoc, + diag::warn_attribute_dllexport_explicit_instantiation_decl); + Diag(A->getLoc(), diag::note_attribute); + break; + } + } + + if (auto *A = ClassTemplate->getTemplatedDecl()->getAttr<DLLExportAttr>()) { + Diag(ExternLoc, + diag::warn_attribute_dllexport_explicit_instantiation_decl); + Diag(A->getLocation(), diag::note_attribute); + } + } // Translate the parser's template argument list in our AST format. TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); |