Author: Haojian Wu Date: 2020-12-14T08:50:41+01:00 New Revision: 6326b098852bea51debe415a85eebd1753151cd0
URL: https://github.com/llvm/llvm-project/commit/6326b098852bea51debe415a85eebd1753151cd0 DIFF: https://github.com/llvm/llvm-project/commit/6326b098852bea51debe415a85eebd1753151cd0.diff LOG: [AST][RecoveryExpr] Preserve type for broken overrload member call expr. Reviewed By: sammccall Differential Revision: https://reviews.llvm.org/D80109 Added: Modified: clang/lib/Sema/SemaOverload.cpp clang/test/AST/ast-dump-recovery.cpp clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 5689efe578fa..13d2125d1a28 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -14300,6 +14300,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, UnbridgedCasts.restore(); OverloadCandidateSet::iterator Best; + bool Succeeded = false; switch (CandidateSet.BestViableFunction(*this, UnresExpr->getBeginLoc(), Best)) { case OR_Success: @@ -14307,7 +14308,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, FoundDecl = Best->FoundDecl; CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl); if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc())) - return ExprError(); + break; // If FoundDecl is diff erent 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 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, // 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 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, 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 index 2a8346eb0d15..a8da2b8ad449 100644 --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -125,6 +125,9 @@ struct Foo2 { double func(); class ForwardClass; ForwardClass createFwd(); + + int overload(); + int overload(int, int); }; void test2(Foo2 f) { // CHECK: RecoveryExpr {{.*}} 'double' @@ -136,6 +139,11 @@ void test2(Foo2 f) { // CHECK-NEXT: `-MemberExpr {{.*}} '<bound member function type>' .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 index ce43720cb2d3..f12e0083fb0c 100644 --- 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 <unsigned n> struct Opaque {}; -template <unsigned n> void expect(Opaque<n> _) {} +template <unsigned n> void expect(Opaque<n> _) {} // expected-note 4 {{candidate function template not viable}} // PR5727 // This just shouldn't crash. @@ -134,14 +134,14 @@ namespace test3 { void test() { expect<0>(Base().foo<int>()); expect<1>(Base().foo<0>()); - expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}} + expect<0>(Derived1().foo<int>()); // 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<int>()); // expected-error {{no matching member function for call to 'foo'}} + expect<0>(Derived2().foo<int>()); // 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<int>()); - 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<int>()); - 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'}} } } _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits