在 2020/2/11 上午10:50, JunMa 写道:
Hi
As title. in maybe_promote_captured_temps, we promote captured temporaries
and co_await_expr into a new BIND_EXPR. As the BIND_EXPR contains
co_await_expr and maybe other function calls, the side effects flag should
be set.

This patch fix one mismatch in cppcoro, the testcase comes from cppcoro
and is reduced by creduce.

Bootstrap and test on X86_64, is it OK?

Regards
JunMa

gcc/cp
2020-02-11  Jun Ma <ju...@linux.alibaba.com>

        * coroutines.cc (maybe_promote_captured_temps): Set side effects
        flag for BIND_EXPR.

gcc/testsuite
2020-02-11  Jun Ma <ju...@linux.alibaba.com>

        * g++.dg/coroutines/torture/lambda-10-co-await-lambda.C: New test.
Hi

Sorry for forgetting the patch. Here it is.

Regards
JunMa
---
 gcc/cp/coroutines.cc                          |  2 +
 .../torture/lambda-10-co-await-lambda.C       | 47 +++++++++++++++++++
 2 files changed, 49 insertions(+)
 create mode 100644 
gcc/testsuite/g++.dg/coroutines/torture/lambda-10-co-await-lambda.C

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index decec4550af..004e0a1a659 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -2735,6 +2735,8 @@ maybe_promote_captured_temps (tree *stmt, void *d)
        }
       BIND_EXPR_BLOCK (aw_bind) = b_block;
 
+      /* Set side effects flag since the BIND_EXPR contains co_await expr.  */
+      TREE_SIDE_EFFECTS (aw_bind) = 1;
       *stmt = aw_bind;
     }
   return res;
diff --git 
a/gcc/testsuite/g++.dg/coroutines/torture/lambda-10-co-await-lambda.C 
b/gcc/testsuite/g++.dg/coroutines/torture/lambda-10-co-await-lambda.C
new file mode 100644
index 00000000000..43d4ff6b77e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/torture/lambda-10-co-await-lambda.C
@@ -0,0 +1,47 @@
+//  { dg-do run }
+
+#include "../coro.h"
+template <typename> struct a;
+struct b {
+  struct c {
+    int await_ready() {return 0;}
+    template <typename d> void await_suspend(d) {}
+    void await_resume() noexcept {}
+  };
+  auto initial_suspend() { return std::suspend_never{}; }
+  auto final_suspend() { return c{}; }
+};
+template <typename> struct e {
+  int f() {return 1;}
+};
+template <> struct e<void> : b {
+  a<void> get_return_object() noexcept;
+  void unhandled_exception();
+};
+template <typename g = void> struct a {
+  using promise_type = e<g>;
+  struct h {
+    std::coroutine_handle<promise_type> j;
+    int await_ready() {return 0;}
+    bool await_suspend(std::coroutine_handle<>) { return false;}
+  };
+  auto operator co_await() {
+    struct awaitable : h {
+      auto await_resume() { return this->j.promise().f(); }
+    };
+    return awaitable{};
+  }
+};
+a<> e<void>::get_return_object() noexcept { return a<>{};}
+
+int main() {
+  auto k = []() -> a<int> { return a<int>{};};
+  int l = 0 ;
+  auto m = [&]() -> a<> {
+    for (int i; i < 100; ++i)
+      l += co_await k();
+  };
+  m();
+  if (l != 100)
+    abort();
+}
-- 
2.19.1.3.ge56e4f7

Reply via email to