diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 7686080ff5..4764ced9b4 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -7943,13 +7943,17 @@ static void AddOverloadedCallCandidate(Sema &S, TemplateArgumentListInfo *ExplicitTemplateArgs, Expr **Args, unsigned NumArgs, OverloadCandidateSet &CandidateSet, - bool PartialOverloading) { + bool PartialOverloading, + bool KnownValid) { NamedDecl *Callee = FoundDecl.getDecl(); if (isa(Callee)) Callee = cast(Callee)->getTargetDecl(); if (FunctionDecl *Func = dyn_cast(Callee)) { - assert(!ExplicitTemplateArgs && "Explicit template arguments?"); + if (ExplicitTemplateArgs) { + assert(!KnownValid && "Explicit template arguments?"); + return; + } S.AddOverloadCandidate(Func, FoundDecl, Args, NumArgs, CandidateSet, false, PartialOverloading); return; @@ -7963,9 +7967,7 @@ static void AddOverloadedCallCandidate(Sema &S, return; } - assert(false && "unhandled case in overloaded call candidate"); - - // do nothing? + assert(!KnownValid && "unhandled case in overloaded call candidate"); } /// \brief Add the overload candidates named by callee and/or found by argument @@ -8016,7 +8018,7 @@ void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE, E = ULE->decls_end(); I != E; ++I) AddOverloadedCallCandidate(*this, I.getPair(), ExplicitTemplateArgs, Args, NumArgs, CandidateSet, - PartialOverloading); + PartialOverloading, /*KnownValid*/ true); if (ULE->requiresADL()) AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false, @@ -8058,13 +8060,15 @@ DiagnoseTwoPhaseLookup(Sema &SemaRef, SourceLocation FnLoc, for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) AddOverloadedCallCandidate(SemaRef, I.getPair(), ExplicitTemplateArgs, Args, NumArgs, - Candidates, false); + Candidates, false, /*KnownValid*/ false); OverloadCandidateSet::iterator Best; - if (Candidates.BestViableFunction(SemaRef, FnLoc, Best) != OR_Success) + if (Candidates.BestViableFunction(SemaRef, FnLoc, Best) != OR_Success) { // No viable functions. Don't bother the user with notes for functions // which don't work and shouldn't be found anyway. + R.clear(); return false; + } // Find the namespaces where ADL would have looked, and suggest // declaring the function there instead. diff --git a/test/SemaTemplate/dependent-names.cpp b/test/SemaTemplate/dependent-names.cpp index f778bd9d2c..7bab5d18d1 100644 --- a/test/SemaTemplate/dependent-names.cpp +++ b/test/SemaTemplate/dependent-names.cpp @@ -262,3 +262,33 @@ namespace PR10053 { } } } + +namespace PR10187 { + namespace A { + template + struct S { + void f() { + for (auto &a : e) + __range(a); // expected-error {{undeclared identifier '__range'}} + } + int e[10]; + }; + void g() { + S().f(); // expected-note {{here}} + } + } + + namespace B { + template void g(); // expected-note {{not viable}} + template void f() { + g(T()); // expected-error {{no matching function}} + } + + namespace { + struct S {}; + } + void g(S); + + template void f(); // expected-note {{here}} + } +}