hokein updated this revision to Diff 308267. hokein added a comment. Herald added a subscriber: lxfind.
rebase and address comments. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D80109/new/ https://reviews.llvm.org/D80109 Files: clang/lib/Sema/SemaCoroutine.cpp clang/lib/Sema/SemaOverload.cpp clang/test/AST/ast-dump-recovery.cpp clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
Index: clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp =================================================================== --- clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp +++ 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 @@ 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'}} } } Index: clang/test/AST/ast-dump-recovery.cpp =================================================================== --- clang/test/AST/ast-dump-recovery.cpp +++ clang/test/AST/ast-dump-recovery.cpp @@ -121,6 +121,21 @@ foo->func(x); } +// CHECK: FunctionDecl {{.*}} test2 +// CHECK-NEXT: |-ParmVarDecl {{.*}} f +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: -RecoveryExpr {{.*}} 'int' contains-errors +// CHECK-NEXT: |-UnresolvedMemberExpr +// CHECK-NEXT: `-DeclRefExpr {{.*}} 'Foo2' +// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1 +struct Foo2 { + int overload(); + int overload(int, int); +}; +void test2(Foo2 f) { + f.overload(1); // verify "int" is preserved +} + // CHECK: |-AlignedAttr {{.*}} alignas // CHECK-NEXT:| `-RecoveryExpr {{.*}} contains-errors // CHECK-NEXT:| `-UnresolvedLookupExpr {{.*}} 'invalid' Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -14239,6 +14239,7 @@ UnbridgedCasts.restore(); OverloadCandidateSet::iterator Best; + bool Succeeded = false; switch (CandidateSet.BestViableFunction(*this, UnresExpr->getBeginLoc(), Best)) { case OR_Success: @@ -14246,7 +14247,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. @@ -14255,7 +14256,8 @@ // being used. if (Method != FoundDecl.getDecl() && DiagnoseUseOfDecl(Method, UnresExpr->getNameLoc())) - return ExprError(); + break; + Succeeded = true; break; case OR_No_Viable_Function: @@ -14265,8 +14267,7 @@ 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( @@ -14274,8 +14275,7 @@ 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( @@ -14283,8 +14283,14 @@ 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) { + std::vector<Expr *> SubExprs = {MemExprE}; + llvm::for_each(Args, [&SubExprs](Expr *E) { SubExprs.push_back(E); }); + return CreateRecoveryExpr(MemExprE->getBeginLoc(), RParenLoc, SubExprs, + chooseRecoveryType(CandidateSet, &Best)); } MemExprE = FixOverloadedFunctionReference(MemExprE, FoundDecl, Method); Index: clang/lib/Sema/SemaCoroutine.cpp =================================================================== --- clang/lib/Sema/SemaCoroutine.cpp +++ clang/lib/Sema/SemaCoroutine.cpp @@ -861,7 +861,7 @@ auto *RD = Promise->getType()->getAsCXXRecordDecl(); if (lookupMember(*this, "await_transform", RD, Loc)) { ExprResult R = buildPromiseCall(*this, Promise, Loc, "await_transform", E); - if (R.isInvalid()) { + if (R.isInvalid() || R.get()->containsErrors()) { Diag(Loc, diag::note_coroutine_promise_implicit_await_transform_required_here) << E->getSourceRange();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits