зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
6594942e98
Коммит
2ced044c34
|
@ -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}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче