https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103039
--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- unshare_expr doesn't do anything wrong. The problem is that because of the select we have firstprivate(__tmp_class_a) clause where __tmp_class_a has type which has struct __class_seltype_A_p * type. Before the r12-1016 change, we clearly firstprivatized that var because gfc_omp_clause_copy_ctor just did: return build2_v (MODIFY_EXPR, dest, src); for that case, so emitted: D.4011 = .omp_data_i->__tmp_class_a; __tmp_class_a = D.4011; which essentially means that the __tmp_class_a var (the pointer) was privatized, but what it points to was shared. Now, since r12-1016 it copies various elements the pointer points to from what the source pointer points to to what the destination pointer points to. But we don't really initialize what dest points to first. I bet we want to privatize what the pointer points to, so we need to emit something like: __class_seltype_A_p temp; __tmp_class_a = &temp; __tmp_class_a->vptr = .omp_data_i->__tmp_class_a->vptr; etc. (not gimplified form). I think the way to achieve this would be make sure to return true from the gfc_omp_privatize_by_reference hook. Tobias, can you please have a look?