When we query is_capture_proxy(), and the scope of the var is one of
the two coroutine helpers, we need to look for the scope information
that pertains to the original function (represented by the ramp now).

We can look up the ramp function from either helper (in practice, the
only caller would be the actor) and if that lookup returns NULL, it
means that the coroutine component is the ramp already and handled by
the usual code path.

tested on x86_64-darwin, linux,
OK for master / backports ?
thanks
Iain

Signed-off-by: Iain Sandoe <i...@sandoe.co.uk>

gcc/cp/ChangeLog:

        PR c++/96517
        * lambda.c (is_capture_proxy): When the scope of the var to
        be tested is a coroutine helper, lookup the scope information
        from the parent (ramp) function.

gcc/testsuite/ChangeLog:

        PR c++/96517
        * g++.dg/coroutines/pr96517.C: New test.
---
 gcc/cp/lambda.c                           |  6 ++++-
 gcc/testsuite/g++.dg/coroutines/pr96517.C | 29 +++++++++++++++++++++++
 3 files changed, 35 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/coroutines/pr96517.C


diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 2e9d38bbe83..c1556480e22 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -244,7 +244,11 @@ is_capture_proxy (tree decl)
          && !(DECL_ARTIFICIAL (decl)
               && DECL_LANG_SPECIFIC (decl)
               && DECL_OMP_PRIVATIZED_MEMBER (decl))
-         && LAMBDA_FUNCTION_P (DECL_CONTEXT (decl)));
+         && (LAMBDA_FUNCTION_P (DECL_CONTEXT (decl))
+             || (DECL_DECLARES_FUNCTION_P (DECL_CONTEXT (decl))
+                 && DECL_COROUTINE_P (DECL_CONTEXT (decl))
+                 && DECL_RAMP_FN (DECL_CONTEXT (decl))
+                 && LAMBDA_FUNCTION_P (DECL_RAMP_FN (DECL_CONTEXT (decl))))));
 }
 
 /* Returns true iff DECL is a capture proxy for a normal capture
diff --git a/gcc/testsuite/g++.dg/coroutines/pr96517.C 
b/gcc/testsuite/g++.dg/coroutines/pr96517.C
new file mode 100644
index 00000000000..9cbac3ebc0d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/pr96517.C
@@ -0,0 +1,29 @@
+// { dg-additional-options " -O1 " }
+#include <coroutine>
+
+struct coroutine {
+    struct promise_type {
+        coroutine get_return_object() { return {}; }
+        void return_void() {}
+        void unhandled_exception() {}
+        auto initial_suspend() noexcept { return std::suspend_never{}; }
+        auto final_suspend() noexcept { return std::suspend_never{}; }
+    };
+};
+
+struct data {
+    constexpr int get() { return 5; }
+};
+
+struct test {
+    data _data;
+
+    void foo() {
+        [this]() -> coroutine {
+            _data.get();
+            co_return;
+        };
+    }
+};
+
+int main() {}
-- 
2.24.3 (Apple Git-128)

Reply via email to