https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127559

--- Comment #4 from Tobias Burnus <burnus at gcc dot gnu.org> ---
In cp/semantics.cc:

finish_omp_target_clauses (location_t loc, tree body, tree *clauses_ptr)
{
...
  if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
    {
      tree lt = TREE_TYPE (t);
      gcc_assert (CLASS_TYPE_P (lt));
      if (!data->lambda_objects_accessed.contains (t)
          /* Do not prepare to create target maps for locally declared
             lambdas or anonymous ones.  */
          && !data->local_decls.contains (t)
          && TREE_CODE (t) != TARGET_EXPR)
        data->lambda_objects_accessed.add (t);

      *walk_subtrees = 0;
      return NULL_TREE;
    }
}

* * *

For the code in question (bottom of comment 0), there is for the first lambda:

   get_omega

which has   data->local_decls.contains (t)  == true.

And then for the second lambda, there is first

   ker

which is also in local_decls – but then additionally an INIT_EXPR:

  (ker.lrn_bwd_kernel()::<lambda()>::<get_omega capture> = get_omega)

where 'ker' is of course still in 'local_decls' - and the RHS is a
TARGET_EXPR - which 'get_omega' being also still in local_decls.

* * *

Not adding but continuing processing (i.e. not setting subtree walk)
will still add the LHS - while just checking the RHS will ICE as

  if (current_object)
    {
      tree this_expr = TREE_OPERAND (current_object, 0);

fails.

* * *

The following seems to be a tad cleaner as comment 3 and seems to work ...

--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -11283,7 +11283,8 @@ finish_omp_target_clauses_r (tree *tp, int
       tree lt = TREE_TYPE (t);
       gcc_assert (CLASS_TYPE_P (lt));

-      if (!data->lambda_objects_accessed.contains (t)
+      if (TREE_CODE(t) != INIT_EXPR
+         && !data->lambda_objects_accessed.contains (t)
          /* Do not prepare to create target maps for locally declared
             lambdas or anonymous ones.  */
          && !data->local_decls.contains (t)

Reply via email to