From: Nick Lewycky Date: Fri, 2 Jan 2015 01:33:12 +0000 (+0000) Subject: Instantiation of a CXXMethodDecl may fail when the parameter type cannot be instantia... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dd03a2db436ea1c99993bada326ee0fe570cf6d8;p=clang Instantiation of a CXXMethodDecl may fail when the parameter type cannot be instantiated. Do not crash in this case. Fixes PR22040! The FIXME in the test is caused by TemplateDeclInstantiator::VisitCXXRecordDecl returning a nullptr instead of creating an invalid decl. This is a common pattern across all of TemplateDeclInstantiator, so I'm not comfortable changing it. The reason it's not invalid in the class template is due to support for an MSVC extension, see r137573. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@225071 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 9ba9c14559..40e86175b2 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2360,8 +2360,10 @@ Decl * TemplateDeclInstantiator Decl *TemplateDeclInstantiator::VisitClassScopeFunctionSpecializationDecl( ClassScopeFunctionSpecializationDecl *Decl) { CXXMethodDecl *OldFD = Decl->getSpecialization(); - CXXMethodDecl *NewFD = cast(VisitCXXMethodDecl(OldFD, - nullptr, true)); + CXXMethodDecl *NewFD = + cast_or_null(VisitCXXMethodDecl(OldFD, nullptr, true)); + if (!NewFD) + return nullptr; LookupResult Previous(SemaRef, NewFD->getNameInfo(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index 58cb897955..4cc40af7e1 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -182,3 +182,16 @@ namespace SameSignatureAfterInstantiation { }; S s; // expected-note {{instantiation}} } + +namespace PR22040 { + template struct Foobar { + template <> void bazqux(typename T::type) {} // expected-error {{cannot specialize a function 'bazqux' within class scope}} expected-error 2{{cannot be used prior to '::' because it has no members}} + }; + + void test() { + // FIXME: we should suppress the "no member" errors + Foobar::bazqux(); // expected-error{{no member named 'bazqux' in }} expected-note{{in instantiation of template class }} + Foobar::bazqux(); // expected-error{{no member named 'bazqux' in }} expected-note{{in instantiation of template class }} + Foobar::bazqux(3); // expected-error{{no member named 'bazqux' in }} + } +}