Handle CO_AWAIT_EXPR in conversion in co_await_expander.
authorBin Cheng <bin.cheng@linux.alibaba.com>
Thu, 30 Jan 2020 04:10:36 +0000 (12:10 +0800)
committerBin Cheng <bin.cheng@linux.alibaba.com>
Thu, 30 Jan 2020 04:35:46 +0000 (12:35 +0800)
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
gcc/cp/coroutines.cc
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/coroutines/co-await-syntax-09-convert.C [new file with mode: 0644]

index b3075832205fd94d63df82915eeb46169604c9a8..335652451bd8c2fa5bb0bfe057f88d42266f1e08 100644 (file)
@@ -1,3 +1,7 @@
+2020-01-30  Bin Cheng  <bin.cheng@linux.alibaba.com>
+
+       * coroutines.cc (co_await_expander): Handle type conversion case.
+
 2020-01-29  Jason Merrill  <jason@redhat.com>
 
        PR c++/90333
index e8a6a4033f6f20694c0ce344d0fe1019d7f99d2c..7deb6f6e3e455f65643835cbdb5092db74b68d52 100644 (file)
@@ -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:
index 57d612002a0d434acefd8e39b1c63813d2996d29..30e804b2969dde88fe2db3b2b084144dc692d0c5 100644 (file)
@@ -1,3 +1,7 @@
+2020-01-30  Bin Cheng  <bin.cheng@linux.alibaba.com>
+
+       * g++.dg/coroutines/co-await-syntax-09-convert.C: New test.
+
 2020-01-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/92706
        * gcc.target/i386/pr93319-1a.c: Don't include <stdio.h>.
        (test1): Replace printf with __builtin_printf.
 
-2020-01-21  Bin Cheng  <bin.linux@linux.alibaba.com>
+2020-01-21  Bin Cheng  <bin.cheng@linux.alibaba.com>
 
        * 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 (file)
index 0000000..dde0bab
--- /dev/null
@@ -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{}; }