Hi! For firstprivate vars, even when implicit, the privatized entity is what the reference refers to; if its copy ctor or dtor need instantiation, doing this at gimplification time is too late, therefore we should handle it during genericization like we handle non-reference firstprivatized vars.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk, queued for backporting. 2017-09-14 Jakub Jelinek <ja...@redhat.com> PR c++/81314 * cp-gimplify.c (omp_var_to_track): Look through references. (omp_cxx_notice_variable): Likewise. * testsuite/libgomp.c++/pr81314.C: New test. --- gcc/cp/cp-gimplify.c.jj 2017-09-01 09:26:24.000000000 +0200 +++ gcc/cp/cp-gimplify.c 2017-09-14 15:31:54.526100238 +0200 @@ -895,6 +895,8 @@ omp_var_to_track (tree decl) tree type = TREE_TYPE (decl); if (is_invisiref_parm (decl)) type = TREE_TYPE (type); + else if (TREE_CODE (type) == REFERENCE_TYPE) + type = TREE_TYPE (type); while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); if (type == error_mark_node || !CLASS_TYPE_P (type)) @@ -947,6 +949,8 @@ omp_cxx_notice_variable (struct cp_gener tree type = TREE_TYPE (decl); if (is_invisiref_parm (decl)) type = TREE_TYPE (type); + else if (TREE_CODE (type) == REFERENCE_TYPE) + type = TREE_TYPE (type); while (TREE_CODE (type) == ARRAY_TYPE) type = TREE_TYPE (type); get_copy_ctor (type, tf_none); --- libgomp/testsuite/libgomp.c++/pr81314.C.jj 2017-09-14 15:51:17.883604562 +0200 +++ libgomp/testsuite/libgomp.c++/pr81314.C 2017-09-14 15:50:56.000000000 +0200 @@ -0,0 +1,38 @@ +// PR c++/81314 +// { dg-do link } + +template <int N> +struct S { + S () { s = 0; } + S (const S &x) { s = x.s; } + ~S () {} + int s; +}; + +void +foo (S<2> &x) +{ + #pragma omp taskloop + for (int i = 0; i < 100; ++i) + x.s++; +} + +void +bar (S<3> &x) +{ + #pragma omp task + x.s++; +} + +int +main () +{ + S<2> s; + S<3> t; + #pragma omp parallel + #pragma omp master + { + foo (s); + bar (t); + } +} Jakub