在 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