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);
}
?