[coroutines] Build co_await/yield_expr with unknown_type in processing_template_decl phase

Message ID 6ac2b47f-b1b2-5fb3-99f7-66597387018b@linux.alibaba.com
State New
Headers show
Series
  • [coroutines] Build co_await/yield_expr with unknown_type in processing_template_decl phase
Related show

Commit Message

JunMa Feb. 5, 2020, 6:14 a.m.
Hi
This patch builds co_await/yield_expr with unknown_type when we can not
know the promise type in processing_template_decl phase. it avoid to
confuse compiler when handing type deduction and conversion.

Bootstrap and test on X86_64, is it OK?

Regards
JunMa

gcc/cp
2020-02-05  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.

gcc/testsuite
2020-02-05  Jun Ma <JunMa@linux.alibaba.com>

         * g++.dg/coroutines/torture/co-await-14-template-traits.C: New 
test.
---
 gcc/cp/coroutines.cc                          |  8 +++----
 gcc/cp/pt.c                                   |  5 ++++
 .../torture/co-await-14-template-traits.C     | 24 +++++++++++++++++++
 3 files changed, 32 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/torture/co-await-14-template-traits.C

Comments

JunMa Feb. 5, 2020, 9:17 a.m. | #1
在 2020/2/5 下午2:14, JunMa 写道:
> Hi

> This patch builds co_await/yield_expr with unknown_type when we can not

> know the promise type in processing_template_decl phase. it avoid to

> confuse compiler when handing type deduction and conversion.

>

> Bootstrap and test on X86_64, is it OK?

>

> Regards

> JunMa

>

Hi
sorry for that '}' was removed, here is the update patch:)

Regards
JunMa
> gcc/cp

> 2020-02-05  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.

>

> gcc/testsuite

> 2020-02-05  Jun Ma <JunMa@linux.alibaba.com>

>

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

> test.
---
 gcc/cp/coroutines.cc                          |  6 ++---
 gcc/cp/pt.c                                   |  5 ++++
 .../torture/co-await-14-template-traits.C     | 24 +++++++++++++++++++
 3 files changed, 32 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/torture/co-await-14-template-traits.C

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 7525d7c035a..04e56b9a636 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -834,8 +834,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
@@ -912,7 +912,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);
     }
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 40ff3c3a089..cfc3393991e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -26743,6 +26743,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)
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
index 00000000000..4e670b1c308
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/co-await-14-template-traits.C
@@ -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;
+}
JunMa Feb. 10, 2020, 11:42 a.m. | #2
Kindly ping.

Regards
JunMa

在 2020/2/5 下午5:17, JunMa 写道:
> 在 2020/2/5 下午2:14, JunMa 写道:

>> Hi

>> This patch builds co_await/yield_expr with unknown_type when we can not

>> know the promise type in processing_template_decl phase. it avoid to

>> confuse compiler when handing type deduction and conversion.

>>

>> Bootstrap and test on X86_64, is it OK?

>>

>> Regards

>> JunMa

>>

> Hi

> sorry for that '}' was removed, here is the update patch:)

>

> Regards

> JunMa

>> gcc/cp

>> 2020-02-05  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.

>>

>> gcc/testsuite

>> 2020-02-05  Jun Ma <JunMa@linux.alibaba.com>

>>

>>         * g++.dg/coroutines/torture/co-await-14-template-traits.C: 

>> New test.

>

>
JunMa Feb. 27, 2020, 2:16 a.m. | #3
在 2020/2/10 下午7:42, JunMa 写道:
Ping~

Regards
JunMa
> Kindly ping.

>

> Regards

> JunMa

>

> 在 2020/2/5 下午5:17, JunMa 写道:

>> 在 2020/2/5 下午2:14, JunMa 写道:

>>> Hi

>>> This patch builds co_await/yield_expr with unknown_type when we can not

>>> know the promise type in processing_template_decl phase. it avoid to

>>> confuse compiler when handing type deduction and conversion.

>>>

>>> Bootstrap and test on X86_64, is it OK?

>>>

>>> Regards

>>> JunMa

>>>

>> Hi

>> sorry for that '}' was removed, here is the update patch:)

>>

>> Regards

>> JunMa

>>> gcc/cp

>>> 2020-02-05  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.

>>>

>>> gcc/testsuite

>>> 2020-02-05  Jun Ma <JunMa@linux.alibaba.com>

>>>

>>>         * g++.dg/coroutines/torture/co-await-14-template-traits.C: 

>>> New test.

>>

>>

>
Nathan Sidwell March 2, 2020, 2:46 p.m. | #4
On 2/5/20 4:17 AM, JunMa wrote:
> 在 2020/2/5 下午2:14, JunMa 写道:

>> Hi

>> This patch builds co_await/yield_expr with unknown_type when we can not

>> know the promise type in processing_template_decl phase. it avoid to

>> confuse compiler when handing type deduction and conversion.

>>

>> Bootstrap and test on X86_64, is it OK?

>>

>> Regards

>> JunMa

>>

> Hi

> sorry for that '}' was removed, here is the update patch:)

> 

> Regards

> JunMa

>> gcc/cp

>> 2020-02-05  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.

>>

>> gcc/testsuite

>> 2020-02-05  Jun Ma <JunMa@linux.alibaba.com>

>>

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

>> test.


ok


-- 
Nathan Sidwell

Patch

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 7525d7c035a..e380ee24c5f 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -834,9 +834,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
      the promise type, and obtain its return type.  */
@@ -912,9 +911,8 @@  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);
-    }
 
   if (!coro_promise_type_found_p (current_function_decl, kw))
     /* We must be able to look up the "yield_value" method in the scope of
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 40ff3c3a089..cfc3393991e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -26743,6 +26743,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)
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
index 00000000000..4e670b1c308
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/co-await-14-template-traits.C
@@ -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;
+}