Fix PR10187: when diagnosing a two-phase-lookup-related failure, don't assert that any names we find are valid candidates for the call.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133898 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith 2011-06-26 22:19:54 +00:00
Родитель 6594942e98
Коммит 2ced044c34
2 изменённых файлов: 42 добавлений и 8 удалений

Просмотреть файл

@ -7943,13 +7943,17 @@ static void AddOverloadedCallCandidate(Sema &S,
TemplateArgumentListInfo *ExplicitTemplateArgs, TemplateArgumentListInfo *ExplicitTemplateArgs,
Expr **Args, unsigned NumArgs, Expr **Args, unsigned NumArgs,
OverloadCandidateSet &CandidateSet, OverloadCandidateSet &CandidateSet,
bool PartialOverloading) { bool PartialOverloading,
bool KnownValid) {
NamedDecl *Callee = FoundDecl.getDecl(); NamedDecl *Callee = FoundDecl.getDecl();
if (isa<UsingShadowDecl>(Callee)) if (isa<UsingShadowDecl>(Callee))
Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl(); Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl();
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) { if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) {
assert(!ExplicitTemplateArgs && "Explicit template arguments?"); if (ExplicitTemplateArgs) {
assert(!KnownValid && "Explicit template arguments?");
return;
}
S.AddOverloadCandidate(Func, FoundDecl, Args, NumArgs, CandidateSet, S.AddOverloadCandidate(Func, FoundDecl, Args, NumArgs, CandidateSet,
false, PartialOverloading); false, PartialOverloading);
return; return;
@ -7963,9 +7967,7 @@ static void AddOverloadedCallCandidate(Sema &S,
return; return;
} }
assert(false && "unhandled case in overloaded call candidate"); assert(!KnownValid && "unhandled case in overloaded call candidate");
// do nothing?
} }
/// \brief Add the overload candidates named by callee and/or found by argument /// \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) E = ULE->decls_end(); I != E; ++I)
AddOverloadedCallCandidate(*this, I.getPair(), ExplicitTemplateArgs, AddOverloadedCallCandidate(*this, I.getPair(), ExplicitTemplateArgs,
Args, NumArgs, CandidateSet, Args, NumArgs, CandidateSet,
PartialOverloading); PartialOverloading, /*KnownValid*/ true);
if (ULE->requiresADL()) if (ULE->requiresADL())
AddArgumentDependentLookupCandidates(ULE->getName(), /*Operator*/ false, 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) for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
AddOverloadedCallCandidate(SemaRef, I.getPair(), AddOverloadedCallCandidate(SemaRef, I.getPair(),
ExplicitTemplateArgs, Args, NumArgs, ExplicitTemplateArgs, Args, NumArgs,
Candidates, false); Candidates, false, /*KnownValid*/ false);
OverloadCandidateSet::iterator Best; 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 // No viable functions. Don't bother the user with notes for functions
// which don't work and shouldn't be found anyway. // which don't work and shouldn't be found anyway.
R.clear();
return false; return false;
}
// Find the namespaces where ADL would have looked, and suggest // Find the namespaces where ADL would have looked, and suggest
// declaring the function there instead. // declaring the function there instead.

Просмотреть файл

@ -262,3 +262,33 @@ namespace PR10053 {
} }
} }
} }
namespace PR10187 {
namespace A {
template<typename T>
struct S {
void f() {
for (auto &a : e)
__range(a); // expected-error {{undeclared identifier '__range'}}
}
int e[10];
};
void g() {
S<int>().f(); // expected-note {{here}}
}
}
namespace B {
template<typename T> void g(); // expected-note {{not viable}}
template<typename T> void f() {
g<int>(T()); // expected-error {{no matching function}}
}
namespace {
struct S {};
}
void g(S);
template void f<S>(); // expected-note {{here}}
}
}