Index: lib/Sema/SemaTemplate.cpp =================================================================== --- lib/Sema/SemaTemplate.cpp +++ lib/Sema/SemaTemplate.cpp @@ -7825,7 +7825,8 @@ // A member function [...] of a class template can be explicitly // instantiated from the member definition associated with its class // template. - UnresolvedSet<8> Matches; + UnresolvedSet<8> TemplateMatches; + FunctionDecl *NonTemplateMatch = nullptr; TemplateSpecCandidateSet FailedCandidates(D.getIdentifierLoc()); for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end(); P != PEnd; ++P) { @@ -7834,11 +7835,16 @@ if (CXXMethodDecl *Method = dyn_cast(Prev)) { QualType Adjusted = adjustCCAndNoReturn(R, Method->getType()); if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) { - Matches.clear(); + if (Method->getPrimaryTemplate()){ + TemplateMatches.clear(); - Matches.addDecl(Method, P.getAccess()); - if (Method->getTemplateSpecializationKind() == TSK_Undeclared) - break; + TemplateMatches.addDecl(Method, P.getAccess()); + if (Method->getTemplateSpecializationKind() == TSK_Undeclared) + break; + } else { + assert(!NonTemplateMatch && "Found more than one non-template match"); + NonTemplateMatch = Method; + } } } } @@ -7862,22 +7868,25 @@ continue; } - Matches.addDecl(Specialization, P.getAccess()); + TemplateMatches.addDecl(Specialization, P.getAccess()); } + FunctionDecl *Specialization = NonTemplateMatch; // Find the most specialized function template specialization. - UnresolvedSetIterator Result = getMostSpecialized( - Matches.begin(), Matches.end(), FailedCandidates, - D.getIdentifierLoc(), - PDiag(diag::err_explicit_instantiation_not_known) << Name, - PDiag(diag::err_explicit_instantiation_ambiguous) << Name, - PDiag(diag::note_explicit_instantiation_candidate)); - - if (Result == Matches.end()) - return true; + if (!Specialization) { + UnresolvedSetIterator Result = getMostSpecialized( + TemplateMatches.begin(), TemplateMatches.end(), FailedCandidates, + D.getIdentifierLoc(), + PDiag(diag::err_explicit_instantiation_not_known) << Name, + PDiag(diag::err_explicit_instantiation_ambiguous) << Name, + PDiag(diag::note_explicit_instantiation_candidate)); + + if (Result == TemplateMatches.end()) + return true; - // Ignore access control bits, we don't need them for redeclaration checking. - FunctionDecl *Specialization = cast(*Result); + // Ignore access control bits, we don't need them for redeclaration checking. + Specialization = cast(*Result); + } // C++11 [except.spec]p4 // In an explicit instantiation an exception-specification may be specified, Index: test/SemaCXX/pr14211-crash-on-invalid.cpp =================================================================== --- /dev/null +++ test/SemaCXX/pr14211-crash-on-invalid.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s +// Don't crash (PR14211). + +template +struct X { + void bar(T t) {} + void foo(T t, int i) {} + template + void foo(T t, U i) {} +}; + +template class X; // expected-note {{previous explicit instantiation is here}} +template void X::foo(double t, int i); // expected-error {{duplicate explicit instantiation of 'foo'}} +template void X::foo(double t, int i); + + + +template +class A { + void foo(T) {} // expected-note {{previous declaration is here}} + void foo(U) {} // expected-error {{multiple overloads of 'foo' instantiate to the same signature 'void (int)'}} +}; +template void A::foo(int); // expected-note {{in instantiation of template class 'A' requested here}}