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,14 @@ if (CXXMethodDecl *Method = dyn_cast(Prev)) { QualType Adjusted = adjustCCAndNoReturn(R, Method->getType()); if (Context.hasSameUnqualifiedType(Method->getType(), Adjusted)) { - Matches.clear(); - - Matches.addDecl(Method, P.getAccess()); - if (Method->getTemplateSpecializationKind() == TSK_Undeclared) - break; + if (Method->getPrimaryTemplate()){ + TemplateMatches.clear(); + + TemplateMatches.addDecl(Method, P.getAccess()); + if (Method->getTemplateSpecializationKind() == TSK_Undeclared) + break; + } else + NonTemplateMatch = Method; } } } @@ -7862,22 +7866,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,14 @@ +// 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);