aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-04-30 10:42:36 +0100
committerIain Sandoe <iain@sandoe.co.uk>2020-04-30 16:00:39 +0100
commit448c89d590455ed4ab7abc40309b5cf8ec52d13d (patch)
tree61c760c016575511ea8afc83832ea9e1fd5fc36d /gcc
parentaa94a22f5cb337e173d7119ffd5a92f1e607f544 (diff)
downloadgcc-448c89d590455ed4ab7abc40309b5cf8ec52d13d.zip
gcc-448c89d590455ed4ab7abc40309b5cf8ec52d13d.tar.gz
gcc-448c89d590455ed4ab7abc40309b5cf8ec52d13d.tar.bz2
coroutines: Fix handling of artificial vars [PR94886]
The testcase ICEs because the range-based for generates three artificial variables that need to be allocated to the coroutine frame but, when walking the BIND_EXR that contains these, the DECL_INITIAL for one of them refers to an entry appearing later, which means that the frame entry hasn't been allocated when that INITIAL is walked. The solution is to defer walking the DECL_INITIAL/SIZE etc. until all the BIND_EXPR vars have been processed. gcc/cp/ChangeLog: 2020-04-30 Iain Sandoe <iain@sandoe.co.uk> PR c++/94886 * coroutines.cc (transform_local_var_uses): Defer walking the DECL_INITIALs of BIND_EXPR vars until all the frame allocations have been made. gcc/testsuite/ChangeLog: 2020-04-30 Iain Sandoe <iain@sandoe.co.uk> PR c++/94886 * g++.dg/coroutines/pr94886-folly-3.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/coroutines.cc24
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/coroutines/pr94886-folly-3.C15
4 files changed, 43 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 62f997e..1fa0e12 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
2020-04-30 Iain Sandoe <iain@sandoe.co.uk>
+ PR c++/94886
+ * coroutines.cc (transform_local_var_uses): Defer walking
+ the DECL_INITIALs of BIND_EXPR vars until all the frame
+ allocations have been made.
+
+2020-04-30 Iain Sandoe <iain@sandoe.co.uk>
+
PR c++/94883
* coroutines.cc (register_awaits): Update target
expressions for awaitable and suspend handle
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index cb9074e..e90d3d5 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1814,14 +1814,6 @@ transform_local_var_uses (tree *stmt, int *do_subtree, void *d)
/* Re-write the variable's context to be in the actor func. */
DECL_CONTEXT (lvar) = lvd->context;
- /* we need to walk some of the decl trees, which might contain
- references to vars replaced at a higher level. */
- cp_walk_tree (&DECL_INITIAL (lvar), transform_local_var_uses, d,
- NULL);
- cp_walk_tree (&DECL_SIZE (lvar), transform_local_var_uses, d, NULL);
- cp_walk_tree (&DECL_SIZE_UNIT (lvar), transform_local_var_uses, d,
- NULL);
-
/* For capture proxies, this could include the decl value expr. */
if (local_var.is_lambda_capture || local_var.has_value_expr_p)
{
@@ -1843,6 +1835,22 @@ transform_local_var_uses (tree *stmt, int *do_subtree, void *d)
lvd->actor_frame, fld_ref, NULL_TREE);
local_var.field_idx = fld_idx;
}
+ /* FIXME: we should be able to do this in the loop above, but (at least
+ for range for) there are cases where the DECL_INITIAL contains
+ forward references.
+ So, now we've built the revised var in the frame, substitute uses of
+ it in initializers and the bind expr body. */
+ for (lvar = BIND_EXPR_VARS (*stmt); lvar != NULL;
+ lvar = DECL_CHAIN (lvar))
+ {
+ /* we need to walk some of the decl trees, which might contain
+ references to vars replaced at a higher level. */
+ cp_walk_tree (&DECL_INITIAL (lvar), transform_local_var_uses, d,
+ NULL);
+ cp_walk_tree (&DECL_SIZE (lvar), transform_local_var_uses, d, NULL);
+ cp_walk_tree (&DECL_SIZE_UNIT (lvar), transform_local_var_uses, d,
+ NULL);
+ }
cp_walk_tree (&BIND_EXPR_BODY (*stmt), transform_local_var_uses, d, NULL);
/* Now we have processed and removed references to the original vars,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 369ce42..7d5ae75 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2020-04-30 Iain Sandoe <iain@sandoe.co.uk>
+ PR c++/94886
+ * g++.dg/coroutines/pr94886-folly-3.C: New test.
+
+2020-04-30 Iain Sandoe <iain@sandoe.co.uk>
+
PR c++/94883
* g++.dg/coroutines/pr94883-folly-2.C: New test.
diff --git a/gcc/testsuite/g++.dg/coroutines/pr94886-folly-3.C b/gcc/testsuite/g++.dg/coroutines/pr94886-folly-3.C
new file mode 100644
index 0000000..d7bd2c1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr94886-folly-3.C
@@ -0,0 +1,15 @@
+
+#include "coro.h"
+#include "coro1-ret-int-yield-int.h"
+
+#include <array>
+
+coro1
+my_coro ()
+{
+ const std::array<int, 5> expectedValues = {{0, 3, 1, 4, 2}};
+
+ for (int expectedValue : expectedValues) {
+ co_yield expectedValue;
+ }
+}