diff options
author | Nico Weber <nicolasweber@gmx.de> | 2011-12-20 20:32:49 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2011-12-20 20:32:49 +0000 |
commit | c7feca0392f7a55e1efa56fd1579881cd59d03d3 (patch) | |
tree | 6cfbf4c31910f6cce6bfd0e377ad0dd8fcdab0a4 | |
parent | d7f02c6c051673ea1004b1830ad84e69ef712919 (diff) |
Fix a crash on invalid, http://llvm.org/pr11599
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146988 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 12 | ||||
-rw-r--r-- | test/CXX/temp/temp.spec/temp.explicit/p3.cpp | 7 |
2 files changed, 17 insertions, 2 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index e86912a521..7c3165206c 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1709,6 +1709,13 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, << Context.getTypeDeclType(Instantiation); Diag(Pattern->getLocation(), diag::note_template_decl_here); } + + // In general, Instantiation isn't marked invalid to get more than one + // error for multiple undefined instantiations. But the code that does + // explicit declaration -> explicit definition conversion can't handle + // invalid declarations, so mark as invalid in that case. + if (TSK == TSK_ExplicitInstantiationDeclaration) + Instantiation->setInvalidDecl(); return true; } Pattern = PatternDef; @@ -1719,7 +1726,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, MSInfo->setTemplateSpecializationKind(TSK); MSInfo->setPointOfInstantiation(PointOfInstantiation); } else if (ClassTemplateSpecializationDecl *Spec - = dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) { + = dyn_cast<ClassTemplateSpecializationDecl>(Instantiation)) { Spec->setTemplateSpecializationKind(TSK); Spec->setPointOfInstantiation(PointOfInstantiation); } @@ -1888,7 +1895,8 @@ Sema::InstantiateClassTemplateSpecialization( // If this is an explicit instantiation definition, mark the // vtable as used. - if (TSK == TSK_ExplicitInstantiationDefinition) + if (TSK == TSK_ExplicitInstantiationDefinition && + !ClassTemplateSpec->isInvalidDecl()) MarkVTableUsed(PointOfInstantiation, ClassTemplateSpec, true); return false; diff --git a/test/CXX/temp/temp.spec/temp.explicit/p3.cpp b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp index ff1438285e..38ae7688a0 100644 --- a/test/CXX/temp/temp.spec/temp.explicit/p3.cpp +++ b/test/CXX/temp/temp.spec/temp.explicit/p3.cpp @@ -72,3 +72,10 @@ namespace PR7979 { template <typename T> int S<T>::i; template <typename T> void S<T>::S2::h() {} } + +namespace PR11599 { + template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}} + + extern template class BasicStringPiece<int>; // expected-error{{explicit instantiation of undefined template 'PR11599::BasicStringPiece<int>}} + template class BasicStringPiece<int>; +} |