
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.
55 lines
828 B
C
55 lines
828 B
C
// 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 ();
|
|
}
|