Build coroutine expression with unknown_type in processing_template_decl phase.
authorJunMa <JunMa@linux.alibaba.com>
Wed, 5 Feb 2020 05:46:59 +0000 (13:46 +0800)
committerJunMa <JunMa@linux.alibaba.com>
Tue, 3 Mar 2020 03:18:54 +0000 (11:18 +0800)
gcc/cp
        * coroutines.cc (finish_co_await_expr): Build co_await_expr
        with unknown_type_node.
        (finish_co_yield_expr): Ditto.
        *pt.c (type_dependent_expression_p): Set co_await/yield_expr
        with unknown type as dependent.

gcc/testsuite
        * g++.dg/coroutines/torture/co-await-14-template-traits.C: New test.

gcc/cp/ChangeLog
gcc/cp/coroutines.cc
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/coroutines/torture/co-await-14-template-traits.C [new file with mode: 0644]

index bfe8d7949b25dac3d3523247b040df292f7b4d61..edc088ee51d646dff34c90477e87eab5b706dd9d 100644 (file)
@@ -1,3 +1,11 @@
+2020-03-03  Jun Ma <JunMa@linux.alibaba.com>
+
+       * coroutines.cc (finish_co_await_expr): Build co_await_expr
+       with unknown_type_node.
+       (finish_co_yield_expr): Ditto.
+       *pt.c (type_dependent_expression_p): Set co_await/yield_expr
+       with unknown type as dependent.
+
 2020-03-02  Iain Sandoe  <iain@sandoe.co.uk>
 
        * coroutines.cc (struct local_var_info): Adjust to remove the
index 303e6e83d54d86a24be5ba8dbfe8aec96801c46f..966ec0583aa4fb4f00f12c664e1ddc6924f81011 100644 (file)
@@ -847,8 +847,8 @@ finish_co_await_expr (location_t kw, tree expr)
       /* If we don't know the promise type, we can't proceed.  */
       tree functype = TREE_TYPE (current_function_decl);
       if (dependent_type_p (functype) || type_dependent_expression_p (expr))
-       return build5_loc (kw, CO_AWAIT_EXPR, TREE_TYPE (expr), expr, NULL_TREE,
-                          NULL_TREE, NULL_TREE, integer_zero_node);
+       return build5_loc (kw, CO_AWAIT_EXPR, unknown_type_node, expr,
+                          NULL_TREE, NULL_TREE, NULL_TREE, integer_zero_node);
     }
 
   /* We must be able to look up the "await_transform" method in the scope of
@@ -925,7 +925,7 @@ finish_co_yield_expr (location_t kw, tree expr)
       tree functype = TREE_TYPE (current_function_decl);
       /* If we don't know the promise type, we can't proceed.  */
       if (dependent_type_p (functype) || type_dependent_expression_p (expr))
-       return build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (expr), expr,
+       return build2_loc (kw, CO_YIELD_EXPR, unknown_type_node, expr,
                           NULL_TREE);
     }
 
index 622c70b352fc1e96a6a0ccacfb19213db8114cdc..230331f60cbfac09e8cf94d5cf7f696b843ffa5b 100644 (file)
@@ -26701,6 +26701,11 @@ type_dependent_expression_p (tree expression)
       if (TREE_CODE (expression) == SCOPE_REF)
        return false;
 
+      /* CO_AWAIT/YIELD_EXPR with unknown type is always dependent.  */
+      if (TREE_CODE (expression) == CO_AWAIT_EXPR
+         || TREE_CODE (expression) == CO_YIELD_EXPR)
+       return true;
+
       if (BASELINK_P (expression))
        {
          if (BASELINK_OPTYPE (expression)
index 5eae7d8173c46bb9f45e2eba2da1d27d7c50e5f7..6418eb2fd9408971a0f6e5bef86c30f02781479b 100644 (file)
@@ -1,3 +1,7 @@
+2020-03-03  Jun Ma <JunMa@linux.alibaba.com>
+
+       * g++.dg/coroutines/torture/co-await-14-template-traits.C: New test.
+
 2020-03-02  David Malcolm  <dmalcolm@redhat.com>
 
        * gcc.dg/analyzer/CVE-2005-1689-dedupe-issue.c: Add
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/co-await-14-template-traits.C b/gcc/testsuite/g++.dg/coroutines/torture/co-await-14-template-traits.C
new file mode 100644 (file)
index 0000000..4e670b1
--- /dev/null
@@ -0,0 +1,24 @@
+//  { dg-do compile }
+//  Test we create co_await_expr with dependent type rather than type of awaitable class
+
+#include "../coro.h"
+#include "../coro1-ret-int-yield-int.h"
+#include <chrono>
+
+struct TestAwaiter {
+    int recent_test;
+    TestAwaiter(int test) : recent_test{test} {}
+    bool await_ready() { return true; }
+    void await_suspend(coro::coroutine_handle<>) {}
+    int await_resume() { return recent_test;}
+    void return_value(int x) { recent_test = x;}
+};
+
+template <typename Rep, typename Period>
+coro1 test_temparg (std::chrono::duration<Rep, Period> dur)
+{
+       auto sum = co_await TestAwaiter(1);
+       if (!sum)
+        dur.count();
+       co_return 0;
+}