On 4/25/20 11:08 AM, Iain Sandoe wrote:
(WAS  [PATCH] coroutines: Handle lambda capture objects in the way as clang.)

I am sorry to mess you around on this.

It wasn't you who wasn't focussing :)

We changed the argument passed to the promise parameter preview
to match a reference to *this.  However to be consistent with the
other ports, we do need to match the reference transformation in
the traits lookup and the promise allocator lookup.

A few comments ...


gcc/cp/ChangeLog:

2020-04-25  Iain Sandoe  <i...@sandoe.co.uk>

        PR c++/94760
        * coroutines.cc (instantiate_coro_traits): Pass a reference to
        object type rather than a pointer type for 'this', for method
        coroutines.
        (struct param_info): Add a field to hold that the parm is a lambda
        closure pointer.
        (morph_fn_to_coro): Check for lambda closure pointers in the
        args.  Use a reference to *this when building the args list for the
        promise allocator lookup.

gcc/testsuite/ChangeLog:

2020-04-25  Iain Sandoe  <i...@sandoe.co.uk>

        PR c++/94760
        * g++.dg/coroutines/pr94760-mismatched-traits-and-promise-prev.C: New 
test.
---
  gcc/cp/coroutines.cc                          | 52 +++++++++++++++++--
  ...9xxxx-mismatched-traits-and-promise-prev.C | 29 +++++++++++
  2 files changed, 77 insertions(+), 4 deletions(-)
  create mode 100644 
gcc/testsuite/g++.dg/coroutines/pr9xxxx-mismatched-traits-and-promise-prev.C

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 4f254b7fd10..c80a3b716b2 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -296,14 +296,25 @@ instantiate_coro_traits (tree fndecl, location_t kw)
       type.  */
tree functyp = TREE_TYPE (fndecl);
+  tree arg = DECL_ARGUMENTS (fndecl);
+  bool lambda_p = LAMBDA_TYPE_P (DECL_CONTEXT (fndecl));

I think LAMBDA_FUNCTION_P (fndecl) expresses intent better.

@@ -3652,6 +3664,7 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
          The second two entries start out empty - and only get populated
          when we see uses.  */
        param_uses = new hash_map<tree, param_info>;
+      bool lambda_p = LAMBDA_TYPE_P (DECL_CONTEXT (orig));

Likewise.

for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
           arg = DECL_CHAIN (arg))
@@ -3691,7 +3704,17 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
            }
          else
            parm.frame_type = actual_type;
+
          parm.this_ptr = is_this_parameter (arg);
+         if (lambda_p)
+           {
+             parm.lambda_cobj = parm.this_ptr
+                                || (DECL_NAME (arg) == closure_identifier);

i'm confused by the need for || here. Why isn't just the DECL_NAME test needed? The parser appears to give the object parameter that name. (If you do need the parm.this_ptr piece, it suggests somewhere else outside of coro is not being consistent, but ICBW.)

@@ -3831,9 +3854,28 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
        those of the original function.  */
        vec<tree, va_gc> *args = make_tree_vector ();
        vec_safe_push (args, resizeable); /* Space needed.  */
+
        for (tree arg = DECL_ARGUMENTS (orig); arg != NULL;
           arg = DECL_CHAIN (arg))
-       vec_safe_push (args, arg);
+       {
+         param_info *parm_i = param_uses->get (arg);
+         gcc_checking_assert (parm_i);
+         if (parm_i->lambda_cobj)
+           vec_safe_push (args, arg);
+         else if (0 && parm_i->this_ptr)

^^ looks like now-disabled experimental code?


--
Nathan Sidwell

Reply via email to