re PR c++/36308 (OpenMP privatized vars don't get dtors called if they are virtual)

PR c++/36308
	* semantics.c (omp_clause_info_fndecl): New function.
	(finish_omp_clauses): Use it.

	* testsuite/libgomp.c++/ctor-11.C: New test.
	* testsuite/libgomp.c++/ctor-12.C: New test.

From-SVN: r135798
This commit is contained in:
Jakub Jelinek 2008-05-23 13:52:44 +02:00 committed by Jakub Jelinek
parent 3fda325236
commit 7a0112e7a4
5 changed files with 205 additions and 6 deletions

View File

@ -1,3 +1,9 @@
2008-05-23 Jakub Jelinek <jakub@redhat.com>
PR c++/36308
* semantics.c (omp_clause_info_fndecl): New function.
(finish_omp_clauses): Use it.
2008-05-21 Jakub Jelinek <jakub@redhat.com>
PR c++/36023

View File

@ -3334,6 +3334,31 @@ finalize_nrv (tree *tp, tree var, tree result)
htab_delete (data.visited);
}
/* Return the declaration for the function called by CALL_EXPR T,
TYPE is the class type of the clause decl. */
static tree
omp_clause_info_fndecl (tree t, tree type)
{
tree ret = get_callee_fndecl (t);
if (ret)
return ret;
gcc_assert (TREE_CODE (t) == CALL_EXPR);
t = CALL_EXPR_FN (t);
STRIP_NOPS (t);
if (TREE_CODE (t) == OBJ_TYPE_REF)
{
t = cp_fold_obj_type_ref (t, type);
if (TREE_CODE (t) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
return TREE_OPERAND (t, 0);
}
return NULL_TREE;
}
/* For all elements of CLAUSES, validate them vs OpenMP constraints.
Remove any elements from the list that are invalid. */
@ -3677,8 +3702,7 @@ finish_omp_clauses (tree clauses)
if (TREE_CODE (t) == NOP_EXPR)
t = TREE_OPERAND (t, 0);
t = get_callee_fndecl (t);
TREE_VEC_ELT (info, 0) = t;
TREE_VEC_ELT (info, 0) = get_callee_fndecl (t);
}
if ((need_default_ctor || need_copy_ctor)
@ -3700,8 +3724,7 @@ finish_omp_clauses (tree clauses)
if (TREE_CODE (t) == NOP_EXPR)
t = TREE_OPERAND (t, 0);
t = get_callee_fndecl (t);
TREE_VEC_ELT (info, 1) = t;
TREE_VEC_ELT (info, 1) = omp_clause_info_fndecl (t, inner_type);
}
if (need_copy_assignment
@ -3720,8 +3743,7 @@ finish_omp_clauses (tree clauses)
if (TREE_CODE (t) == INDIRECT_REF)
t = TREE_OPERAND (t, 0);
t = get_callee_fndecl (t);
TREE_VEC_ELT (info, 2) = t;
TREE_VEC_ELT (info, 2) = omp_clause_info_fndecl (t, inner_type);
}
if (errorcount != save_errorcount)

View File

@ -1,3 +1,9 @@
2008-05-23 Jakub Jelinek <jakub@redhat.com>
PR c++/36308
* testsuite/libgomp.c++/ctor-11.C: New test.
* testsuite/libgomp.c++/ctor-12.C: New test.
2008-05-15 Janis Johnson <janis187@us.ibm.com>
* testsuite/lib/libgomp.exp: Load torture-options.exp from gcc lib.

View File

@ -0,0 +1,100 @@
// PR c++/36308
// { dg-do run }
#include <omp.h>
#include <assert.h>
#define N 10
struct B
{
static int icount;
static int ccount;
static int dcount;
static int xcount;
B ();
B (const B &);
virtual ~B ();
B& operator= (const B &);
void doit ();
static void clear () { icount = ccount = dcount = xcount = 0; }
};
int B::icount;
int B::ccount;
int B::dcount;
int B::xcount;
B::B ()
{
#pragma omp atomic
icount++;
}
B::B (const B &)
{
#pragma omp atomic
ccount++;
}
B::~B ()
{
#pragma omp atomic
dcount++;
}
void
B::doit ()
{
#pragma omp atomic
xcount++;
}
static int nthreads;
void
test1 ()
{
B b[N];
#pragma omp parallel private (b)
{
#pragma omp master
nthreads = omp_get_num_threads ();
b[0].doit ();
}
}
void
test2 ()
{
B b;
#pragma omp parallel firstprivate (b)
{
#pragma omp single
nthreads = omp_get_num_threads ();
b.doit ();
}
}
int
main ()
{
omp_set_dynamic (0);
omp_set_num_threads (4);
B::clear ();
test1 ();
assert (B::xcount == nthreads);
assert (B::ccount == 0);
assert (B::icount == (nthreads + 1) * N);
assert (B::dcount == (nthreads + 1) * N);
B::clear ();
test2 ();
assert (B::xcount == nthreads);
assert (B::ccount == nthreads);
assert (B::icount == 1);
assert (B::dcount == nthreads + 1);
return 0;
}

View File

@ -0,0 +1,65 @@
// PR c++/36308
// { dg-do run }
extern "C" void abort ();
static int ctors, dtors, copyctors, n, m;
struct A
{
A ()
{
l = 0;
#pragma omp atomic
ctors++;
}
A (const A &x)
{
l = x.l;
#pragma omp atomic
copyctors++;
}
virtual A& operator= (const A &x)
{
l = x.l;
#pragma omp atomic
assignops++;
return *this;
}
virtual ~A ()
{
#pragma omp atomic
dtors++;
}
int l;
static int ctors, dtors, copyctors, assignops;
};
int A::ctors;
int A::dtors;
int A::copyctors;
int A::assignops;
int
main ()
{
A a;
#pragma omp parallel private (a)
{
a.l = 6;
#pragma omp single copyprivate (a)
{
a.l = 3;
}
if (a.l != 3)
abort ();
#pragma omp atomic
n++;
}
if (A::ctors != n + 1
|| A::copyctors != 0
|| A::dtors != n
|| A::assignops != n - 1)
abort ();
return 0;
}