Hi! DECL_OMP_PRIVATIZED_MEMBER vars are artificial vars with DECL_VALUE_EXPR of this->field used just during gimplification and omp lowering/expansion to privatize individual fields in methods when needed. As the following testcase shows, when not in templates, they were handled right, but in templates we actually called cp_finish_decl on them and that can result in their destruction, which is obviously undesirable, we should only destruct the privatized copies of them created in omp lowering.
Fixed thusly. Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk so far. 2022-12-21 Jakub Jelinek <ja...@redhat.com> PR c++/108180 * pt.cc (tsubst_expr): Don't call cp_finish_decl on DECL_OMP_PRIVATIZED_MEMBER vars. * testsuite/libgomp.c++/pr108180.C: New test. --- gcc/cp/pt.cc.jj 2022-12-19 11:09:13.499170642 +0100 +++ gcc/cp/pt.cc 2022-12-20 12:13:59.406097521 +0100 @@ -18895,6 +18895,11 @@ tsubst_expr (tree t, tree args, tsubst_f maybe_push_decl (decl); if (VAR_P (decl) + && DECL_LANG_SPECIFIC (decl) + && DECL_OMP_PRIVATIZED_MEMBER (decl)) + break; + + if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl) && TREE_TYPE (pattern_decl) != error_mark_node) ndecl = tsubst_decomp_names (decl, pattern_decl, args, --- libgomp/testsuite/libgomp.c++/pr108180.C.jj 2022-12-20 12:54:21.077793817 +0100 +++ libgomp/testsuite/libgomp.c++/pr108180.C 2022-12-20 12:53:04.740905961 +0100 @@ -0,0 +1,55 @@ +// PR c++/108180 +// { dg-do run } + +struct A { + A () { ++a; } + A (A &&) = delete; + A (const A &) { ++a; } + A &operator= (const A &) = delete; + A &operator= (A &&) = delete; + ~A () { --a; } + static int a; +}; +int A::a = 0; + +struct B { + A a; + template <int N> + int + foo () + { + int res = 0; + #pragma omp parallel for if(false) firstprivate(a) + for (int i = 0; i < 64; ++i) + res += i; + return res; + } + int + bar () + { + int res = 0; + #pragma omp parallel for if(false) firstprivate(a) + for (int i = 0; i < 64; ++i) + res += i; + return res; + } +}; + +int +main () +{ + { + B b; + if (b.foo<0> () != 2016) + __builtin_abort (); + } + if (A::a != 0) + __builtin_abort (); + { + B b; + if (b.bar () != 2016) + __builtin_abort (); + } + if (A::a != 0) + __builtin_abort (); +} Jakub