diff options
author | Jakub Jelinek <jakub@redhat.com> | 2022-12-21 09:05:27 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2022-12-21 09:10:03 +0100 |
commit | 1119902b6c7c1c50123ed85ec1def8be4772d68c (patch) | |
tree | 1ba7afc4a41e3bcc01571d5ac240aa1af86cea8f | |
parent | 0d1b5446bf17c14fce3428a005446539292fe27e (diff) | |
download | gcc-1119902b6c7c1c50123ed85ec1def8be4772d68c.zip gcc-1119902b6c7c1c50123ed85ec1def8be4772d68c.tar.gz gcc-1119902b6c7c1c50123ed85ec1def8be4772d68c.tar.bz2 |
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 <jakub@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.
-rw-r--r-- | gcc/cp/pt.cc | 5 | ||||
-rw-r--r-- | libgomp/testsuite/libgomp.c++/pr108180.C | 55 |
2 files changed, 60 insertions, 0 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 2d90298..e68c749 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -18874,6 +18874,11 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl) 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, diff --git a/libgomp/testsuite/libgomp.c++/pr108180.C b/libgomp/testsuite/libgomp.c++/pr108180.C new file mode 100644 index 0000000..452910c --- /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 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 (); +} |