summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-06-26 22:19:54 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-06-26 22:19:54 +0000
commit2ced044c34311d8e6301f2b4566f4b612bc8b628 (patch)
treed04b42f4b30e9158b31e2acfc6693a7149d821bf
parent6594942e98e25640f226aba622eb76bcaf0a521c (diff)
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
-rw-r--r--lib/Sema/SemaOverload.cpp20
-rw-r--r--test/SemaTemplate/dependent-names.cpp30
2 files changed, 42 insertions, 8 deletions
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<UsingShadowDecl>(Callee))
Callee = cast<UsingShadowDecl>(Callee)->getTargetDecl();
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,
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<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}}
+ }
+}