在 2020/1/21 上午9:31, JunMa 写道:
在 2020/1/20 下午11:49, Nathan Sidwell 写道:
On 1/20/20 12:18 AM, JunMa wrote:
Hi
This patch adds lookup_awaitable_member, it outputs error messages when any of the await_ready/suspend/resume functions are missing in awaitable class.

This patch also add some error check on return value of build_co_await since we
may failed to build co_await_expr.

Bootstrap and test on X86_64, is it OK?

Regards
JunMa

gcc/cp
2020-01-20  Jun Ma <ju...@linux.alibaba.com>

         * coroutines.cc (lookup_awaitable_member): Lookup an awaitable member.          (build_co_await): Use lookup_awaitable_member instead of lookup_member.          (finish_co_yield_expr, finish_co_await_expr): Add error check on return
         value of build_co_await.

gcc/testsuite
2020-01-20  Jun Ma <ju...@linux.alibaba.com>

         * g++.dg/coroutines/coro1-missing-await-method.C: New test.


1) you're mixing two distinct changes, the one about the error message and the one about changing error_mark_node.

   tree op = build_co_await (kw, a, CO_AWAIT_SUSPEND_POINT);
-  TREE_SIDE_EFFECTS (op) = 1;
-  SET_EXPR_LOCATION (op, kw);
-
+  if (op != error_mark_node)
+    {
+      TREE_SIDE_EFFECTS (op) = 1;
+      SET_EXPR_LOCATION (op, kw);
+    }
   return op;
 }

these two fragments are ok, as a separate patch.


ok, I'll split it.
+/* Lookup an Awaitable member, which should be await_ready, await_suspend
+   or await_resume  */
+
+static tree
+lookup_awaitable_member (tree await_type, tree member_id, location_t loc)
+{
+  tree aw_memb
+    = lookup_member (await_type, member_id,
+             /*protect*/ 1, /*want_type*/ 0, tf_warning_or_error);
fwiw '/*foo=*/expr' is the canonical form -- i know Iain wasn't consistent, and it looks like I may have missed a few places in review.

ok.
+  if (aw_memb == NULL_TREE || aw_memb == error_mark_node)
+    {
+      error_at (loc, "no member named %qE in %qT", member_id, await_type);
+      return error_mark_node;
+    }
+  return aw_memb;
+}

This looks wrong.  lookup_member is being passed tf_warning_or_error, so it should already be emitting a diagnostic, for the cases where something is found, but is ambiguous or whatever.  So, I think you only want a diagnostic here when you get NULL_TREE back.

you are right, I follow with same code of lookup_promise_member, I'll update both.

Regards
JunMa
nathan

Hi nathan,
attachment is the updated patch which check error_mark_node of build_co_coawait.

Regards
JunMa

gcc/cp
2020-01-21  Jun Ma <ju...@linux.alibaba.com>

         * coroutines.cc (finish_co_await_expr): Add error check on return
         value of build_co_await.
         (finish_co_yield_expr,): Ditto.
---
 gcc/cp/coroutines.cc | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 43f03f7c49a..bd3656562ec 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -810,8 +810,11 @@ finish_co_await_expr (location_t kw, tree expr)
 
   /* Now we want to build co_await a.  */
   tree op = build_co_await (kw, a, CO_AWAIT_SUSPEND_POINT);
-  TREE_SIDE_EFFECTS (op) = 1;
-  SET_EXPR_LOCATION (op, kw);
+  if (op != error_mark_node)
+    {
+      TREE_SIDE_EFFECTS (op) = 1;
+      SET_EXPR_LOCATION (op, kw);
+    }
 
   return op;
 }
@@ -874,9 +877,11 @@ finish_co_yield_expr (location_t kw, tree expr)
      promise transform_await().  */
 
   tree op = build_co_await (kw, yield_call, CO_YIELD_SUSPEND_POINT);
-
-  op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
-  TREE_SIDE_EFFECTS (op) = 1;
+  if (op != error_mark_node)
+    {
+      op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
+      TREE_SIDE_EFFECTS (op) = 1;
+    }
 
   return op;
 }
-- 
2.19.1.3.ge56e4f7

Reply via email to