On 11/29/24 8:43 AM, Iain Sandoe wrote:
Tested on x86_64-darwin, x86_64/powerpc64-linux, on folly and more
widely by Sam. There are possibly additional BZ dups that will be
covered (this fixes 117231, a P1). OK for trunk?
thanks
Iain
--- 8< ---
In the current implementation, statement expressions were intentionally
unsupported (as a C++ extension). However since they are quite heavily
used by end-users and also now emitted by the compiler in some cases
we are now working to add them. This first patch ensures that we
recurse into statement expressions (and therefore handle coroutine
keywords that might appear inside them).
PR c++/115851
PR c++/116914
PR c++/117231
gcc/cp/ChangeLog:
* coroutines.cc (await_statement_expander): Walk into
statement expressions.
(await_statement_walker): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/pr115851.C: New test.
* g++.dg/coroutines/pr116914.C: New test.
* g++.dg/coroutines/pr117231.C: New test.
Signed-off-by: Iain Sandoe <i...@sandoe.co.uk>
---
gcc/cp/coroutines.cc | 22 ++++++++++++
gcc/testsuite/g++.dg/coroutines/pr115851.C | 35 +++++++++++++++++++
gcc/testsuite/g++.dg/coroutines/pr116914.C | 40 ++++++++++++++++++++++
gcc/testsuite/g++.dg/coroutines/pr117231.C | 21 ++++++++++++
4 files changed, 118 insertions(+)
create mode 100644 gcc/testsuite/g++.dg/coroutines/pr115851.C
create mode 100644 gcc/testsuite/g++.dg/coroutines/pr116914.C
create mode 100644 gcc/testsuite/g++.dg/coroutines/pr117231.C
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index cdf61d89109..5764475a7de 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -2128,6 +2128,14 @@ await_statement_expander (tree *stmt, int *do_subtree,
void *d)
}
else if (EXPR_P (*stmt))
{
+ /* Look for ({}) at the top level - just recurse into these. */
+ if (TREE_CODE (*stmt) == EXPR_STMT)
+ {
+ tree inner = EXPR_STMT_EXPR (*stmt);
+ if (TREE_CODE (inner) == STATEMENT_LIST
+ || TREE_CODE (inner) == BIND_EXPR)
+ return NULL_TREE; // process contents
+ }
How about adding EXPR_STMT to the set of codes that we immediately
return null for at the top of the function:
/* Process a statement at a time. */
if (STATEMENT_CLASS_P (*stmt)
|| TREE_CODE (*stmt) == BIND_EXPR
|| TREE_CODE (*stmt) == CLEANUP_POINT_EXPR)
return NULL_TREE; /* Just process the sub-trees. */
? Incidentally, why don't we also do that for STATEMENT_LIST? The
explicit handling just below seems equivalent to what walk_tree_1 does.
process_one_statement (stmt, d);
*do_subtree = 0; /* Done subtrees. */
}
@@ -3857,6 +3865,20 @@ await_statement_walker (tree *stmt, int *do_subtree,
void *d)
if (!(cp_walk_tree (stmt, find_any_await, &await_ptr, &visited)))
return NULL_TREE; /* Nothing special to do here. */
+ /* Handle statement expressions. */
+ if (TREE_CODE (expr) == EXPR_STMT)
+ {
+ tree inner = EXPR_STMT_EXPR (expr);
+ if (TREE_CODE (inner) == STATEMENT_LIST
+ || TREE_CODE (inner) == BIND_EXPR)
+ {
+ res = cp_walk_tree (&EXPR_STMT_EXPR (expr),
+ await_statement_walker, d, NULL);
+ *do_subtree = 0;
+ return res;
+ }
+ }
As in the other function, how about returning NULL_TREE early for
EXPR_STMT and STATEMENT_LIST?
Jason