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