This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp] c++ ctors vs array types
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 23 Oct 2005 23:26:07 -0700
- Subject: [gomp] c++ ctors vs array types
More testing reveals a few think-o's in the array support.
The cp-gimplify.c changes are in order to handle gimplification of
C++ FOR_STMT (created by build_vec_init), after normal gimplification
of the function.
r~
* cp-gimplify.c (struct cp_gimplify_ctx): Remove.
(bc_label): New.
(begin_bc_block, finish_bc_block): Use it.
(push_context, pop_context): Remove.
(cp_genericize): Don't use them. Assert bc_label is null.
* semantics.c (finish_omp_clauses): Create a fake data element
of TYPE for probing ctors.
* testsuite/libgomp.c++/ctor-6.C: New.
* testsuite/libgomp.c++/ctor-7.C: New.
* testsuite/libgomp.c++/ctor-8.C: New.
* testsuite/libgomp.c++/ctor-9.C: New.
Index: gcc/cp/cp-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-gimplify.c,v
retrieving revision 1.20.4.3
diff -u -p -d -r1.20.4.3 cp-gimplify.c
--- gcc/cp/cp-gimplify.c 21 Oct 2005 00:04:25 -0000 1.20.4.3
+++ gcc/cp/cp-gimplify.c 24 Oct 2005 06:19:23 -0000
@@ -37,30 +37,9 @@ Software Foundation, 51 Franklin Street,
enum bc_t { bc_break = 0, bc_continue = 1 };
-static struct cp_gimplify_ctx
-{
- /* Stack of labels which are targets for "break" or "continue",
- linked through TREE_CHAIN. */
- tree current_label[2];
-} *ctxp;
-
-static void
-push_context (void)
-{
- gcc_assert (!ctxp);
- ctxp = ((struct cp_gimplify_ctx *)
- xcalloc (1, sizeof (struct cp_gimplify_ctx)));
-}
-
-static void
-pop_context (void)
-{
- gcc_assert (ctxp
- && !ctxp->current_label[0]
- && !ctxp->current_label[1]);
- free (ctxp);
- ctxp = NULL;
-}
+/* Stack of labels which are targets for "break" or "continue",
+ linked through TREE_CHAIN. */
+static tree bc_label[2];
/* Begin a scope which can be exited by a break or continue statement. BC
indicates which.
@@ -71,8 +50,8 @@ static tree
begin_bc_block (enum bc_t bc)
{
tree label = create_artificial_label ();
- TREE_CHAIN (label) = ctxp->current_label[bc];
- ctxp->current_label[bc] = label;
+ TREE_CHAIN (label) = bc_label[bc];
+ bc_label[bc] = label;
return label;
}
@@ -86,7 +65,7 @@ begin_bc_block (enum bc_t bc)
static tree
finish_bc_block (enum bc_t bc, tree label, tree body)
{
- gcc_assert (label == ctxp->current_label[bc]);
+ gcc_assert (label == bc_label[bc]);
if (TREE_USED (label))
{
@@ -99,7 +78,7 @@ finish_bc_block (enum bc_t bc, tree labe
body = sl;
}
- ctxp->current_label[bc] = TREE_CHAIN (label);
+ bc_label[bc] = TREE_CHAIN (label);
TREE_CHAIN (label) = NULL_TREE;
return body;
}
@@ -110,7 +89,7 @@ finish_bc_block (enum bc_t bc, tree labe
static tree
build_bc_goto (enum bc_t bc)
{
- tree label = ctxp->current_label[bc];
+ tree label = bc_label[bc];
if (label == NULL_TREE)
{
@@ -716,7 +695,8 @@ cp_genericize (tree fndecl)
pointer_set_destroy (p_set);
/* Do everything else. */
- push_context ();
c_genericize (fndecl);
- pop_context ();
+
+ gcc_assert (bc_label[bc_break] == NULL);
+ gcc_assert (bc_label[bc_continue] == NULL);
}
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.475.4.18
diff -u -p -d -r1.475.4.18 semantics.c
--- gcc/cp/semantics.c 24 Oct 2005 04:01:30 -0000 1.475.4.18
+++ gcc/cp/semantics.c 24 Oct 2005 06:19:23 -0000
@@ -3523,6 +3523,15 @@ finish_omp_clauses (tree clauses)
{
int save_errorcount = errorcount;
+ /* For the copy constructor and assignment op, we need
+ an object of the appropriate type. Pretend with an
+ otherwise bogus INDIRECT_REF. */
+ if (type != TREE_TYPE (t))
+ {
+ t = build_int_cst (build_pointer_type (type), 0);
+ t = build1 (INDIRECT_REF, type, t);
+ }
+
if (need_default_ctor && TYPE_NEEDS_CONSTRUCTING (type))
{
build_special_member_call (NULL_TREE, complete_ctor_identifier,
Index: libgomp/testsuite/libgomp.c++/ctor-6.C
===================================================================
RCS file: libgomp/testsuite/libgomp.c++/ctor-6.C
diff -N libgomp/testsuite/libgomp.c++/ctor-6.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.c++/ctor-6.C 24 Oct 2005 06:19:30 -0000
@@ -0,0 +1,50 @@
+// { dg-do run }
+
+#include <omp.h>
+#include <assert.h>
+
+struct B
+{
+ static int count;
+ static B *expected;
+
+ B& operator=(const B &);
+};
+
+int B::count;
+B * B::expected;
+
+B& B::operator= (const B &b)
+{
+ assert (&b == expected);
+ assert (this != expected);
+ #pragma omp atomic
+ count++;
+ return *this;
+}
+
+static int nthreads;
+
+void foo()
+{
+ #pragma omp parallel
+ {
+ B b;
+ #pragma omp single copyprivate(b)
+ {
+ nthreads = omp_get_num_threads ();
+ B::expected = &b;
+ }
+ }
+}
+
+int main()
+{
+ omp_set_dynamic (0);
+ omp_set_num_threads (4);
+ foo();
+
+ assert (B::count == nthreads-1);
+
+ return 0;
+}
Index: libgomp/testsuite/libgomp.c++/ctor-7.C
===================================================================
RCS file: libgomp/testsuite/libgomp.c++/ctor-7.C
diff -N libgomp/testsuite/libgomp.c++/ctor-7.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.c++/ctor-7.C 24 Oct 2005 06:19:30 -0000
@@ -0,0 +1,67 @@
+// { dg-do run }
+
+#include <omp.h>
+#include <assert.h>
+
+#define N 10
+
+struct B
+{
+ static int icount;
+ static int dcount;
+ static int xcount;
+
+ B();
+ B(const B &);
+ ~B();
+ B& operator=(const B &);
+ void doit();
+};
+
+int B::icount;
+int B::dcount;
+int B::xcount;
+
+B::B()
+{
+ #pragma omp atomic
+ icount++;
+}
+
+B::~B()
+{
+ #pragma omp atomic
+ dcount++;
+}
+
+void B::doit()
+{
+ #pragma omp atomic
+ xcount++;
+}
+
+static int nthreads;
+
+void foo()
+{
+ B b[N];
+ #pragma omp parallel private(b)
+ {
+ #pragma omp master
+ nthreads = omp_get_num_threads ();
+ b[0].doit();
+ }
+}
+
+int main()
+{
+ omp_set_dynamic (0);
+ omp_set_num_threads (4);
+ foo();
+
+ assert (B::xcount == nthreads);
+ assert (B::icount == (nthreads+1)*N);
+ assert (B::dcount == (nthreads+1)*N);
+
+ return 0;
+}
Index: libgomp/testsuite/libgomp.c++/ctor-8.C
===================================================================
RCS file: libgomp/testsuite/libgomp.c++/ctor-8.C
diff -N libgomp/testsuite/libgomp.c++/ctor-8.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.c++/ctor-8.C 24 Oct 2005 06:19:30 -0000
@@ -0,0 +1,76 @@
+// { dg-do run }
+
+#include <omp.h>
+#include <assert.h>
+
+#define N 10
+#define THR 4
+
+struct B
+{
+ B();
+ B(const B &);
+ ~B();
+ B& operator=(const B &);
+ void doit();
+};
+
+static B *base;
+static B *threadbase;
+static unsigned cmask[THR];
+static unsigned dmask[THR];
+
+#pragma omp threadprivate(threadbase)
+
+B::B()
+{
+ assert (base == 0);
+}
+
+B::B(const B &b)
+{
+ unsigned index = &b - base;
+ assert (index < N);
+ cmask[omp_get_thread_num()] |= 1u << index;
+}
+
+B::~B()
+{
+ if (threadbase)
+ {
+ unsigned index = this - threadbase;
+ assert (index < N);
+ dmask[omp_get_thread_num()] |= 1u << index;
+ }
+}
+
+void foo()
+{
+ B b[N];
+
+ base = b;
+
+ #pragma omp parallel firstprivate(b)
+ {
+ assert (omp_get_num_threads () == THR);
+ threadbase = b;
+ }
+
+ threadbase = 0;
+}
+
+int main()
+{
+ omp_set_dynamic (0);
+ omp_set_num_threads (THR);
+ foo();
+
+ for (int i = 0; i < THR; ++i)
+ {
+ unsigned xmask = (1u << N) - 1;
+ assert (cmask[i] == xmask);
+ assert (dmask[i] == xmask);
+ }
+
+ return 0;
+}
Index: libgomp/testsuite/libgomp.c++/ctor-9.C
===================================================================
RCS file: libgomp/testsuite/libgomp.c++/ctor-9.C
diff -N libgomp/testsuite/libgomp.c++/ctor-9.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.c++/ctor-9.C 24 Oct 2005 06:19:30 -0000
@@ -0,0 +1,59 @@
+// { dg-do run }
+
+#include <omp.h>
+#include <assert.h>
+
+#define N 10
+#define THR 4
+
+struct B
+{
+ B& operator=(const B &);
+};
+
+static B *base;
+static B *threadbase;
+static int singlethread;
+#pragma omp threadprivate(threadbase)
+
+static unsigned cmask[THR];
+
+B& B::operator= (const B &b)
+{
+ unsigned sindex = &b - base;
+ unsigned tindex = this - threadbase;
+ assert(sindex < N);
+ assert(sindex == tindex);
+ cmask[omp_get_thread_num ()] |= 1u << tindex;
+ return *this;
+}
+
+void foo()
+{
+ #pragma omp parallel
+ {
+ B b[N];
+ threadbase = b;
+ #pragma omp single copyprivate(b)
+ {
+ assert(omp_get_num_threads () == THR);
+ singlethread = omp_get_thread_num ();
+ base = b;
+ }
+ }
+}
+
+int main()
+{
+ omp_set_dynamic (0);
+ omp_set_num_threads (THR);
+ foo();
+
+ for (int i = 0; i < THR; ++i)
+ if (i == singlethread)
+ assert(cmask[singlethread] == 0);
+ else
+ assert(cmask[i] == (1u << N) - 1);
+
+ return 0;
+}