Hi! Another bug I've ran into while working on OpenMP 5.0 range for support.
For collapse(2) and higher taskloops, if there is any clause that needs a cpyfn callback (e.g. firstprivate with non-POD, or VLA), we wouldn't be copying over the temporaries needed for collapsed loop; without cpyfn the default memcpy that copies the passed in data to the task arg area handles that already. Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk, queued for backports. 2018-07-17 Jakub Jelinek <ja...@redhat.com> PR middle-end/86542 * omp-low.c (create_task_copyfn): Copy over also fields corresponding to _looptemp_ clauses, other than the first two. * testsuite/libgomp.c++/pr86542.C: New test. --- gcc/omp-low.c.jj 2018-06-22 19:17:12.219437746 +0200 +++ gcc/omp-low.c 2018-07-17 10:18:02.551015945 +0200 @@ -7026,6 +7026,7 @@ create_task_copyfn (gomp_task *task_stmt splay_tree_node n; struct omp_taskcopy_context tcctx; location_t loc = gimple_location (task_stmt); + size_t looptempno = 0; child_fn = gimple_omp_task_copy_fn (task_stmt); child_cfun = DECL_STRUCT_FUNCTION (child_fn); @@ -7139,6 +7140,15 @@ create_task_copyfn (gomp_task *task_stmt t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); append_to_statement_list (t, &list); break; + case OMP_CLAUSE__LOOPTEMP_: + /* Fields for first two _looptemp_ clauses are initialized by + GOMP_taskloop*, the rest are handled like firstprivate. */ + if (looptempno < 2) + { + looptempno++; + break; + } + /* FALLTHRU */ case OMP_CLAUSE_FIRSTPRIVATE: decl = OMP_CLAUSE_DECL (c); if (is_variable_sized (decl)) @@ -7164,7 +7174,10 @@ create_task_copyfn (gomp_task *task_stmt src = decl; dst = build_simple_mem_ref_loc (loc, arg); dst = omp_build_component_ref (dst, f); - t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src); + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__LOOPTEMP_) + t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src); + else + t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src); append_to_statement_list (t, &list); break; case OMP_CLAUSE_PRIVATE: --- libgomp/testsuite/libgomp.c++/pr86542.C.jj 2018-07-17 10:20:02.214127004 +0200 +++ libgomp/testsuite/libgomp.c++/pr86542.C 2018-07-17 10:19:39.207105565 +0200 @@ -0,0 +1,37 @@ +// PR middle-end/86542 + +struct S { int s; S (); ~S (); S (const S &); }; +S s; + +S::S () +{ +} + +S::~S () +{ +} + +S::S (const S &x) +{ + s = x.s; +} + +__attribute__((noipa)) void +foo (int i, int j, int k, S s) +{ + if (i != 0 || j != 0 || k != 0 || s.s != 12) + __builtin_abort (); +} + +int +main () +{ + volatile int inc = 16, jnc = 16, knc = 16; + s.s = 12; + #pragma omp taskloop collapse (3) firstprivate (s) + for (int i = 0; i < 16; i += inc) + for (int j = 0; j < 16; j += jnc) + for (int k = 0; k < 16; k += knc) + foo (i, j, k, s); + return 0; +} Jakub