This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [gomp] Fix multiple threadprivate declarations (PR 24455)
On Thursday 20 October 2005 23:16, Daniel Berlin wrote:
> VAR_DECL is derived from struct tree_decl_with_vis, which has 11 empty
> bits if you needed them.
>
OK, thanks.
Richard, how about this version? It adds a bitfield in tree_decl_with_vis
that can be shared by C and C++. It also fixes the hackery you had
pointed out before in the merge code.
I tried adding the same error messages to the C++ front end but ran into
more trouble than I could handle. We fail g++.dg/tls/diag-1.C because:
struct A {
static __thread int i;
};
__thread int A::i = 42;
that triggers the error message. The 'i' inside struct A was marked with
TLS_NONE while the 'i' in the A::i was marked with TLS_MODEL_LOCAL_EXEC.
Perhaps I didn't place the check in the right spot, but I was getting lost
in the C++ FE and this wasn't directly related to the bug I'm fixing. So,
I will leave this up to a C++ maintainer to deal with.
Thanks.
2005-10-21 Diego Novillo <dnovillo@redhat.com>
gcc/
PR 24455
* tree.h (struct tree_decl_with_vis): Add bitfield
threadprivate_p.
(DECL_THREADPRIVATE_P): Define.
* c-parser.c (c_parser_omp_threadprivate): Set it.
Do not error out if DECL_THREADPRIVATE_P is set already.
* c-decl.c (diagnose_mismatched_decls): Do not diagnose TLS
decls marked with #pragma omp threadprivate.
(merge_decls): Merge DECL_THREADPRIVATE_P.
gcc/cp/
PR 24455
* decl.c (duplicate_decls): Merge DECL_THREADPRIVATE_P.
* semantics.c (finish_omp_threadprivate): Set
DECL_THREADPRIVATE_P.
Do not error out if DECL_THREADPRIVATE_P is set already.
libgomp/
PR 24455
* testsuite/libgomp.c++/pr24455-1.C: New test.
* testsuite/libgomp.c++/pr24455.C: New test.
* testsuite/libgomp.dg/pr24455-1.c: New test.
* testsuite/libgomp.dg/pr24455.c: New test.
Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.662.4.12
diff -d -u -p -r1.662.4.12 c-decl.c
--- gcc/c-decl.c 9 Oct 2005 01:01:21 -0000 1.662.4.12
+++ gcc/c-decl.c 21 Oct 2005 04:00:12 -0000
@@ -1383,8 +1383,11 @@ diagnose_mismatched_decls (tree newdecl,
else if (TREE_CODE (newdecl) == VAR_DECL)
{
/* Only variables can be thread-local, and all declarations must
- agree on this property. */
- if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl))
+ agree on this property. If OLDDECL had been declared
+ threadprivate, then it need not be marked again, so this
+ check is unnecessary. */
+ if (DECL_THREAD_LOCAL_P (newdecl) != DECL_THREAD_LOCAL_P (olddecl)
+ && !DECL_THREADPRIVATE_P (olddecl))
{
if (DECL_THREAD_LOCAL_P (newdecl))
error ("thread-local declaration of %q+D follows "
@@ -1671,6 +1674,13 @@ merge_decls (tree newdecl, tree olddecl,
if (DECL_INITIAL (newdecl) == 0)
DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
+ /* Merge the threadprivate attribute. */
+ if (TREE_CODE (olddecl) == VAR_DECL && DECL_THREADPRIVATE_P (olddecl))
+ {
+ DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl);
+ DECL_THREADPRIVATE_P (newdecl) = 1;
+ }
+
if (CODE_CONTAINS_STRUCT (TREE_CODE (olddecl), TS_DECL_WITH_VIS))
{
/* Merge the unused-warning information. */
Index: gcc/c-parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parser.c,v
retrieving revision 2.17.4.36
diff -d -u -p -r2.17.4.36 c-parser.c
--- gcc/c-parser.c 20 Oct 2005 09:02:08 -0000 2.17.4.36
+++ gcc/c-parser.c 21 Oct 2005 04:00:13 -0000
@@ -7694,10 +7694,15 @@ c_parser_omp_threadprivate (c_parser *pa
{
tree v = TREE_PURPOSE (t);
- if (TREE_USED (v))
+ /* If V had already been marked threadprivate, it doesn't matter
+ whether it had been used prior to this point. */
+ if (TREE_USED (v) && !DECL_THREADPRIVATE_P (v))
error ("%qE declared %<threadprivate%> after first use", v);
else
- DECL_TLS_MODEL (v) = decl_default_tls_model (v);
+ {
+ DECL_TLS_MODEL (v) = decl_default_tls_model (v);
+ DECL_THREADPRIVATE_P (v) = 1;
+ }
}
c_parser_skip_to_pragma_eol (parser);
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.735.4.23
diff -d -u -p -r1.735.4.23 tree.h
--- gcc/tree.h 20 Oct 2005 09:02:09 -0000 1.735.4.23
+++ gcc/tree.h 21 Oct 2005 04:00:14 -0000
@@ -2497,6 +2497,11 @@ struct tree_parm_decl GTY(())
/* Used to indicate that the DECL is a dllimport. */
#define DECL_DLLIMPORT_P(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.dllimport_flag)
+/* Record whether a variable has been declared threadprivate by
+ #pragma omp threadprivate. */
+#define DECL_THREADPRIVATE_P(DECL) \
+ VAR_DECL_CHECK (DECL)->decl_with_vis.threadprivate_p
+
/* DECL_BASED_ON_RESTRICT_P records whether a VAR_DECL is a temporary
based on a variable with a restrict qualified type. If it is,
DECL_RESTRICT_BASE returns the restrict qualified variable on which
@@ -2590,6 +2595,7 @@ struct tree_decl_with_vis GTY(())
unsigned based_on_restrict_p : 1;
/* Used by C++. Might become a generic decl flag. */
unsigned shadowed_for_var_p : 1;
+ unsigned threadprivate_p : 1;
/* Don't belong to VAR_DECL exclusively. */
unsigned in_system_header_flag : 1;
Index: gcc/cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1403.4.9
diff -d -u -p -r1.1403.4.9 decl.c
--- gcc/cp/decl.c 17 Oct 2005 00:40:49 -0000 1.1403.4.9
+++ gcc/cp/decl.c 21 Oct 2005 04:00:17 -0000
@@ -1546,6 +1546,13 @@ duplicate_decls (tree newdecl, tree oldd
|= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl);
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl)
|= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl);
+
+ /* Merge the threadprivate attribute from OLDDECL into NEWDECL. */
+ if (DECL_THREADPRIVATE_P (olddecl))
+ {
+ DECL_TLS_MODEL (newdecl) = DECL_TLS_MODEL (olddecl);
+ DECL_THREADPRIVATE_P (newdecl) = 1;
+ }
}
/* Do this after calling `merge_types' so that default
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.475.4.12
diff -d -u -p -r1.475.4.12 semantics.c
--- gcc/cp/semantics.c 20 Oct 2005 09:54:19 -0000 1.475.4.12
+++ gcc/cp/semantics.c 21 Oct 2005 04:00:18 -0000
@@ -3534,10 +3534,15 @@ finish_omp_threadprivate (tree vars)
{
tree v = TREE_PURPOSE (t);
- if (TREE_USED (v))
+ /* If V had already been marked threadprivate, it doesn't matter
+ whether it had been used prior to this point. */
+ if (TREE_USED (v) && !DECL_THREADPRIVATE_P (v))
error ("%qE declared %<threadprivate%> after first use", v);
else
- DECL_TLS_MODEL (v) = decl_default_tls_model (v);
+ {
+ DECL_TLS_MODEL (v) = decl_default_tls_model (v);
+ DECL_THREADPRIVATE_P (v) = 1;
+ }
}
}
Index: libgomp/testsuite/libgomp.c++/pr24455-1.C
===================================================================
RCS file: libgomp/testsuite/libgomp.c++/pr24455-1.C
diff -N libgomp/testsuite/libgomp.c++/pr24455-1.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.c++/pr24455-1.C 21 Oct 2005 04:00:20 -0000
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+extern int i;
+#pragma omp threadprivate (i)
+
+int i;
Index: libgomp/testsuite/libgomp.c++/pr24455.C
===================================================================
RCS file: libgomp/testsuite/libgomp.c++/pr24455.C
diff -N libgomp/testsuite/libgomp.c++/pr24455.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.c++/pr24455.C 21 Oct 2005 04:00:20 -0000
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-additional-sources pr24455-1.C } */
+
+extern "C" void abort (void);
+
+extern int i;
+#pragma omp threadprivate(i)
+
+int main()
+{
+ i = 0;
+
+#pragma omp parallel default(none) num_threads(10)
+ {
+ i++;
+#pragma omp barrier
+ if (i != 1)
+ abort ();
+ }
+
+ return 0;
+}
Index: libgomp/testsuite/libgomp.dg/pr24455-1.c
===================================================================
RCS file: libgomp/testsuite/libgomp.dg/pr24455-1.c
diff -N libgomp/testsuite/libgomp.dg/pr24455-1.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.dg/pr24455-1.c 21 Oct 2005 04:00:20 -0000
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+extern int i;
+#pragma omp threadprivate (i)
+
+int i;
Index: libgomp/testsuite/libgomp.dg/pr24455.c
===================================================================
RCS file: libgomp/testsuite/libgomp.dg/pr24455.c
diff -N libgomp/testsuite/libgomp.dg/pr24455.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libgomp/testsuite/libgomp.dg/pr24455.c 21 Oct 2005 04:00:20 -0000
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* { dg-additional-sources pr24455-1.c } */
+
+extern void abort (void);
+
+extern int i;
+#pragma omp threadprivate(i)
+
+int main()
+{
+ i = 0;
+
+#pragma omp parallel default(none) num_threads(10)
+ {
+ i++;
+#pragma omp barrier
+ if (i != 1)
+ abort ();
+ }
+
+ return 0;
+}