105 lines
3.1 KiB
Diff
105 lines
3.1 KiB
Diff
|
2008-02-18 Jakub Jelinek <jakub@redhat.com>
|
||
|
|
||
|
PR c++/34964
|
||
|
PR c++/35244
|
||
|
* semantics.c (finish_omp_threadprivate): Do nothing for error_operand_p
|
||
|
vars. Afterwards ensure v is VAR_DECL.
|
||
|
|
||
|
* gcc.dg/gomp/pr34964.c: New test.
|
||
|
* g++.dg/gomp/pr34964.C: New test.
|
||
|
* gcc.dg/gomp/pr35244.c: New test.
|
||
|
* g++.dg/gomp/pr35244.C: New test.
|
||
|
|
||
|
--- gcc/cp/semantics.c.jj 2008-02-18 10:51:04.000000000 +0100
|
||
|
+++ gcc/cp/semantics.c 2008-02-18 13:53:58.000000000 +0100
|
||
|
@@ -3742,9 +3742,14 @@ finish_omp_threadprivate (tree vars)
|
||
|
{
|
||
|
tree v = TREE_PURPOSE (t);
|
||
|
|
||
|
+ if (error_operand_p (v))
|
||
|
+ ;
|
||
|
+ else if (TREE_CODE (v) != VAR_DECL)
|
||
|
+ error ("%<threadprivate%> %qD is not file, namespace "
|
||
|
+ "or block scope variable", 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)
|
||
|
+ else if (TREE_USED (v)
|
||
|
&& (DECL_LANG_SPECIFIC (v) == NULL
|
||
|
|| !CP_DECL_THREADPRIVATE_P (v)))
|
||
|
error ("%qE declared %<threadprivate%> after first use", v);
|
||
|
--- gcc/testsuite/gcc.dg/gomp/pr35244.c.jj 2008-02-18 14:08:00.000000000 +0100
|
||
|
+++ gcc/testsuite/gcc.dg/gomp/pr35244.c 2008-02-18 14:07:44.000000000 +0100
|
||
|
@@ -0,0 +1,20 @@
|
||
|
+/* PR c++/35244 */
|
||
|
+/* { dg-do compile } */
|
||
|
+/* { dg-require-effective-target tls_native } */
|
||
|
+/* { dg-options "-fopenmp" } */
|
||
|
+
|
||
|
+int v1;
|
||
|
+typedef struct A A;
|
||
|
+typedef int i;
|
||
|
+#pragma omp threadprivate (i) /* { dg-error "expected identifier before" } */
|
||
|
+#pragma omp threadprivate (A) /* { dg-error "expected identifier before" } */
|
||
|
+#pragma omp threadprivate (v1)
|
||
|
+
|
||
|
+void foo ()
|
||
|
+{
|
||
|
+ static int v4;
|
||
|
+ {
|
||
|
+ static int v5;
|
||
|
+#pragma omp threadprivate (v4, v5)
|
||
|
+ }
|
||
|
+}
|
||
|
--- gcc/testsuite/gcc.dg/gomp/pr34964.c.jj 2008-02-18 13:23:42.000000000 +0100
|
||
|
+++ gcc/testsuite/gcc.dg/gomp/pr34964.c 2008-02-18 14:08:08.000000000 +0100
|
||
|
@@ -0,0 +1,6 @@
|
||
|
+/* PR c++/34964 */
|
||
|
+/* { dg-do compile } */
|
||
|
+/* { dg-options "-fopenmp" } */
|
||
|
+
|
||
|
+char x[] = 0; /* { dg-error "invalid initializer" } */
|
||
|
+#pragma omp threadprivate (x)
|
||
|
--- gcc/testsuite/g++.dg/gomp/pr35244.C.jj 2008-02-18 14:05:37.000000000 +0100
|
||
|
+++ gcc/testsuite/g++.dg/gomp/pr35244.C 2008-02-18 14:07:16.000000000 +0100
|
||
|
@@ -0,0 +1,30 @@
|
||
|
+// PR c++/35244
|
||
|
+// { dg-do compile }
|
||
|
+// { dg-require-effective-target tls_native }
|
||
|
+// { dg-options "-fopenmp" }
|
||
|
+
|
||
|
+int v1;
|
||
|
+namespace N1
|
||
|
+{
|
||
|
+ int v2;
|
||
|
+}
|
||
|
+namespace N2
|
||
|
+{
|
||
|
+ int v3;
|
||
|
+}
|
||
|
+using N1::v2;
|
||
|
+using namespace N2;
|
||
|
+struct A;
|
||
|
+typedef int i;
|
||
|
+#pragma omp threadprivate (i) // { dg-error "is not file, namespace or block scope variable" }
|
||
|
+#pragma omp threadprivate (A) // { dg-error "is not file, namespace or block scope variable" }
|
||
|
+#pragma omp threadprivate (v1, v2, v3)
|
||
|
+
|
||
|
+void foo ()
|
||
|
+{
|
||
|
+ static int v4;
|
||
|
+ {
|
||
|
+ static int v5;
|
||
|
+#pragma omp threadprivate (v4, v5)
|
||
|
+ }
|
||
|
+}
|
||
|
--- gcc/testsuite/g++.dg/gomp/pr34964.C.jj 2008-02-18 13:23:25.000000000 +0100
|
||
|
+++ gcc/testsuite/g++.dg/gomp/pr34964.C 2008-02-18 13:23:03.000000000 +0100
|
||
|
@@ -0,0 +1,6 @@
|
||
|
+// PR c++/34964
|
||
|
+// { dg-do compile }
|
||
|
+// { dg-options "-fopenmp" }
|
||
|
+
|
||
|
+char x[] = 0; // { dg-error "initializer fails to determine size" }
|
||
|
+#pragma omp threadprivate (x)
|