diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -14300,6 +14300,7 @@ UnbridgedCasts.restore(); OverloadCandidateSet::iterator Best; + bool Succeeded = false; switch (CandidateSet.BestViableFunction(*this, UnresExpr->getBeginLoc(), Best)) { case OR_Success: @@ -14307,7 +14308,7 @@ FoundDecl = Best->FoundDecl; CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl); if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc())) - return ExprError(); + break; // If FoundDecl is different from Method (such as if one is a template // and the other a specialization), make sure DiagnoseUseOfDecl is // called on both. @@ -14316,7 +14317,8 @@ // being used. if (Method != FoundDecl.getDecl() && DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc())) - return ExprError(); + break; + Succeeded = true; break; case OR_No_Viable_Function: @@ -14326,27 +14328,25 @@ PDiag(diag::err_ovl_no_viable_member_function_in_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AllCandidates, Args); - // FIXME: Leaking incoming expressions! - return ExprError(); - + break; case OR_Ambiguous: CandidateSet.NoteCandidates( PartialDiagnosticAt(UnresExpr->getMemberLoc(), PDiag(diag::err_ovl_ambiguous_member_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AmbiguousCandidates, Args); - // FIXME: Leaking incoming expressions! - return ExprError(); - + break; case OR_Deleted: CandidateSet.NoteCandidates( PartialDiagnosticAt(UnresExpr->getMemberLoc(), PDiag(diag::err_ovl_deleted_member_call) << DeclName << MemExprE->getSourceRange()), *this, OCD_AllCandidates, Args); - // FIXME: Leaking incoming expressions! - return ExprError(); + break; } + // Overload resolution fails, try to recover. + if (!Succeeded) + return BuildRecoveryExpr(chooseRecoveryType(CandidateSet, &Best)); MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method); diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -125,6 +125,9 @@ double func(); class ForwardClass; ForwardClass createFwd(); + + int overload(); + int overload(int, int); }; void test2(Foo2 f) { // CHECK: RecoveryExpr {{.*}} 'double' @@ -136,6 +139,11 @@ // CHECK-NEXT: `-MemberExpr {{.*}} '' .createFwd // CHECK-NEXT: `-DeclRefExpr {{.*}} 'f' f.createFwd(); + // CHECK: RecoveryExpr {{.*}} 'int' contains-errors + // CHECK-NEXT: |-UnresolvedMemberExpr + // CHECK-NEXT: `-DeclRefExpr {{.*}} 'Foo2' + // CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 + f.overload(1); } // CHECK: |-AlignedAttr {{.*}} alignas diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp --- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp +++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp @@ -9,7 +9,7 @@ // parameter types in a base class (rather than conflicting). template struct Opaque {}; -template void expect(Opaque _) {} +template void expect(Opaque _) {} // expected-note 4 {{candidate function template not viable}} // PR5727 // This just shouldn't crash. @@ -134,14 +134,14 @@ void test() { expect<0>(Base().foo()); expect<1>(Base().foo<0>()); - expect<0>(Derived1().foo()); // expected-error {{no matching member function for call to 'foo'}} + expect<0>(Derived1().foo()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}} expect<2>(Derived1().foo<0>()); - expect<0>(Derived2().foo()); // expected-error {{no matching member function for call to 'foo'}} + expect<0>(Derived2().foo()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}} expect<2>(Derived2().foo<0>()); expect<3>(Derived3().foo()); - expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} + expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}} expect<3>(Derived4().foo()); - expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} + expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}} expected-error {{no matching function for call to 'expect'}} } }