Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
The use of TARGET_EXPR in get_member_function_from_ptrfunc since r13-9563
didn't match the expectations of flatten_await_stmt; the latter isn't
prepared to handle reuse of a TARGET_EXPR. Most places in the front-end
only reuse the TARGET_EXPR_SLOT, not the whole TARGET_EXPR, but that's
awkward for get_member_function_from_ptrfunc, so let's make it work.
PR c++/121094
PR c++/117259
gcc/cp/ChangeLog:
* coroutines.cc (replace_proxy): Handle TARGET_EXPR from.
(flatten_await_stmt): Pass it.
gcc/testsuite/ChangeLog:
* g++.dg/coroutines/pmf-121094.C: New test.
---
gcc/cp/coroutines.cc | 8 ++++---
gcc/testsuite/g++.dg/coroutines/pmf-121094.C | 23 ++++++++++++++++++++
2 files changed, 28 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/coroutines/pmf-121094.C
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 46ec8c0a953..f4df662bbcb 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -2087,7 +2087,9 @@ replace_proxy (tree *here, int *do_subtree, void *d)
{
proxy_replace *data = (proxy_replace *) d;
- if (*here == data->from)
+ if (*here == data->from
+ || (TREE_CODE (data->from) == TARGET_EXPR
+ && *here == TARGET_EXPR_SLOT (data->from)))
{
*here = data->to;
*do_subtree = 0;
@@ -3326,8 +3328,8 @@ flatten_await_stmt (var_nest_node *n, hash_set<tree>
*promoted,
= new var_nest_node (var, init, n->prev, n);
/* We have to replace the target expr... */
*v.entry = var;
- /* ... and any uses of its var. */
- proxy_replace pr = {TARGET_EXPR_SLOT (t), var};
+ /* ... and any other uses of it or its slot. */
+ proxy_replace pr = {t, var};
cp_walk_tree (&n->init, replace_proxy, &pr, NULL);
/* Compiler-generated temporaries can also have uses in
following arms of compound expressions, which will be listed
diff --git a/gcc/testsuite/g++.dg/coroutines/pmf-121094.C
b/gcc/testsuite/g++.dg/coroutines/pmf-121094.C
new file mode 100644
index 00000000000..786b2f1b315
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pmf-121094.C
@@ -0,0 +1,23 @@
+// PR c++/121094
+
+#include <coroutine>
+
+struct Future {
+ struct promise_type {
+ Future get_return_object() { return {}; }
+ std::suspend_never initial_suspend() noexcept { return {}; }
+ std::suspend_never final_suspend() noexcept { return {}; }
+ void return_void() {}
+ void unhandled_exception() {}
+ };
+ bool await_ready() { return true; }
+ void await_suspend(std::coroutine_handle<>) {}
+ void await_resume() {}
+};
+
+struct Foo {
+ Future test(Future (Foo::*fn)()) {
+ co_await (this->*fn)();
+ co_return;
+ }
+};
--
2.54.0