summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2015-01-15 21:18:30 +0000
committerHans Wennborg <hans@hanshq.net>2015-01-15 21:18:30 +0000
commitfd76d91366016494ef1915ae9481d81ed61d339d (patch)
tree7ce3bda05b3757be60d8c0dd8c3ec6a412203bbd /clang/lib
parente2ab0f17cf322b4384186ad392b1ea9abbbc23c4 (diff)
downloadbcm5719-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.cpp11
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp24
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);
OpenPOWER on IntegriCloud