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

--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
6.0 [282:21-32] and [283:1-5] doesn't seem to be considering other lambdas
captured by reference or value inside of a lambda, the rules don't seem to
recurse.
So maybe then
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -11273,25 +11273,32 @@ finish_omp_target_clauses_r (tree *tp, int
*walk_subtrees, void *ptr)
     {
       if (tree block = BIND_EXPR_BLOCK (t))
        for (tree var = BLOCK_VARS (block); var; var = DECL_CHAIN (var))
-         if (!data->local_decls.contains (var))
+         if ((VAR_P (var)
+              || TREE_CODE (var) == PARM_DECL
+              || TREE_CODE (var) == RESULT_DECL)
+             && !data->local_decls.contains (var))
            data->local_decls.add (var);
       return NULL_TREE;
     }

-  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;
-    }
+  if (tree lt = TREE_TYPE (t))
+    if (LAMBDA_TYPE_P (lt))
+      {
+       gcc_assert (CLASS_TYPE_P (lt));
+
+       if (TREE_CODE (t) == TARGET_EXPR
+           && !data->local_decls.contains (TARGET_EXPR_SLOT (t)))
+         data->local_decls.add (TARGET_EXPR_SLOT (t));
+
+       if ((VAR_P (t)
+            || TREE_CODE (t) == PARM_DECL
+            || TREE_CODE (t) == RESULT_DECL)
+           && !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))
+         data->lambda_objects_accessed.add (t);
+      }

   return NULL_TREE;
 }
but haven't done any testing on this, and one certainly needs to have e.g.
testcase for that passing of a lambda closure by value to a function (and guess
invoking it in that function).
Thus
template <typename T>
int
bar (T x)
{
  return x ();
}

void
foo (int x)
{
  auto b = [&] { return x; };
  #pragma omp target
    {
      if (bar (b) != 42)
        __builtin_abort ();
    }
}

int
main ()
{
  foo (42);
}
?

Reply via email to