]> granicus.if.org Git - clang/commitdiff
Fix PR10187: when diagnosing a two-phase-lookup-related failure, don't assert that...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sun, 26 Jun 2011 22:19:54 +0000 (22:19 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sun, 26 Jun 2011 22:19:54 +0000 (22:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133898 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/SemaTemplate/dependent-names.cpp

index 7686080ff581397c6f6d1e7ccffa9442d331bf46..4764ced9b468281dfd4f7af7ecc212980a7f1051 100644 (file)
@@ -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.
index f778bd9d2cd0ff94d449708bde15360464c13aaf..7bab5d18d1ad27b40fe40dd5ba454145f7b82f8f 100644 (file)
@@ -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}}
+  }
+}