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 | expand |
在 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; +}
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. > >
在 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. >> >> >
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
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; +}