From 3b35b3d4cc26816d1c6342b880f303b577ecbb84 Mon Sep 17 00:00:00 2001 From: Bin Cheng Date: Thu, 30 Jan 2020 12:10:36 +0800 Subject: [PATCH] Handle CO_AWAIT_EXPR in conversion in co_await_expander. Function co_await_expander expands CO_AWAIT_EXPR and inserts expanded code before result of co_await is used, however, it doesn't cover the type conversion case and leads to gimplify ICE. This patch fixes it. gcc/cp * coroutines.cc (co_await_expander): Handle type conversion case. gcc/testsuite * g++.dg/coroutines/co-await-syntax-09-convert.C: New test. --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/coroutines.cc | 8 +++++++ gcc/testsuite/ChangeLog | 6 ++++- .../coroutines/co-await-syntax-09-convert.C | 23 +++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/coroutines/co-await-syntax-09-convert.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b3075832205..335652451bd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2020-01-30 Bin Cheng + + * coroutines.cc (co_await_expander): Handle type conversion case. + 2020-01-29 Jason Merrill PR c++/90333 diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index e8a6a4033f6..7deb6f6e3e4 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -1357,6 +1357,9 @@ co_await_expander (tree *stmt, int * /*do_subtree*/, void *d) &buried_stmt, NULL)) saved_co_await = r; } + else if ((stmt_code == CONVERT_EXPR || stmt_code == NOP_EXPR) + && TREE_CODE (TREE_OPERAND (stripped_stmt, 0)) == CO_AWAIT_EXPR) + saved_co_await = TREE_OPERAND (stripped_stmt, 0); if (!saved_co_await) return NULL_TREE; @@ -1514,6 +1517,11 @@ co_await_expander (tree *stmt, int * /*do_subtree*/, void *d) default: /* not likely to work .. but... */ append_to_statement_list (resume_call, &stmt_list); break; + case CONVERT_EXPR: + case NOP_EXPR: + TREE_OPERAND (stripped_stmt, 0) = resume_call; + append_to_statement_list (saved_statement, &stmt_list); + break; case INIT_EXPR: case MODIFY_EXPR: case CALL_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 57d612002a0..30e804b2969 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2020-01-30 Bin Cheng + + * g++.dg/coroutines/co-await-syntax-09-convert.C: New test. + 2020-01-30 Jakub Jelinek PR tree-optimization/92706 @@ -946,7 +950,7 @@ * gcc.target/i386/pr93319-1a.c: Don't include . (test1): Replace printf with __builtin_printf. -2020-01-21 Bin Cheng +2020-01-21 Bin Cheng * g++.dg/coroutines/co-await-void_type.C: New test. diff --git a/gcc/testsuite/g++.dg/coroutines/co-await-syntax-09-convert.C b/gcc/testsuite/g++.dg/coroutines/co-await-syntax-09-convert.C new file mode 100644 index 00000000000..dde0bab00cf --- /dev/null +++ b/gcc/testsuite/g++.dg/coroutines/co-await-syntax-09-convert.C @@ -0,0 +1,23 @@ +// { dg-additional-options "-std=c++17 -w" } + +#include "coro.h" + +class mycoro { +public: + class promise_type { + public: + std::suspend_always initial_suspend() const noexcept { return {}; } + std::suspend_always final_suspend() const noexcept { return {}; } + void unhandled_exception() noexcept { } + mycoro get_return_object() { return mycoro{}; } + }; +}; + +class await { +public: + bool await_ready() const noexcept { return false; } + bool await_suspend(std::coroutine_handle<>) noexcept {return true;} + mycoro await_resume() { return mycoro{}; } +}; + +mycoro foo(mycoro source) { (void) co_await await{}; } -- 2.30.2