From 1119902b6c7c1c50123ed85ec1def8be4772d68c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 21 Dec 2022 09:05:27 +0100 Subject: [PATCH] openmp: Don't try to destruct DECL_OMP_PRIVATIZED_MEMBER vars [PR108180] 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. 2022-12-21 Jakub Jelinek 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 | 5 +++ libgomp/testsuite/libgomp.c++/pr108180.C | 55 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 libgomp/testsuite/libgomp.c++/pr108180.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 2d902988a43..e68c74913f5 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -18873,6 +18873,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) tree asmspec_tree = NULL_TREE; 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) diff --git a/libgomp/testsuite/libgomp.c++/pr108180.C b/libgomp/testsuite/libgomp.c++/pr108180.C new file mode 100644 index 00000000000..452910cebeb --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr108180.C @@ -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 + 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 (); +}