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

Reply via email to