Hi!

finish_omp_clauses calls require_complete_type, but that returns t
immediately if processing_template_decl, so we need to check
COMPLETE_TYPE_P before calling cxx_omp_create_clause_info.
Additionally, for copyin/copyprivate we need to call require_complete_type
too.  While the OpenMP standard doesn't mention anything about complete
types in copyin/copyprivate restrictions, that is only because
threadprivate directive requires complete type.  If one mixes __thread
with copyin/copyprivate, we could have there incomplete type though.

Both issues fixed thusly, regtested on x86_64-linux, committed to trunk/4.6.

2011-05-30  Jakub Jelinek  <ja...@redhat.com>

        PR c++/49223
        * semantics.c (finish_omp_clauses): Call require_complete_type
        even for copyin/copyprivate clauses.  Only call
        cxx_omp_create_clause_info if inner_type is COMPLETE_TYPE_P.

        * g++.dg/gomp/pr49223-1.C: New test.
        * g++.dg/gomp/pr49223-2.C: New test.

--- gcc/cp/semantics.c.jj       2011-05-25 16:30:03.000000000 +0200
+++ gcc/cp/semantics.c  2011-05-30 13:33:08.000000000 +0200
@@ -4041,12 +4041,13 @@ finish_omp_clauses (tree clauses)
          break;
        }
 
-      if (need_complete_non_reference)
+      if (need_complete_non_reference || need_copy_assignment)
        {
          t = require_complete_type (t);
          if (t == error_mark_node)
            remove = true;
-         else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE)
+         else if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE
+                  && need_complete_non_reference)
            {
              error ("%qE has reference type for %qs", t, name);
              remove = true;
@@ -4088,6 +4090,7 @@ finish_omp_clauses (tree clauses)
         Save the results, because later we won't be in the right context
         for making these queries.  */
       if (CLASS_TYPE_P (inner_type)
+         && COMPLETE_TYPE_P (inner_type)
          && (need_default_ctor || need_copy_ctor || need_copy_assignment)
          && !type_dependent_expression_p (t)
          && cxx_omp_create_clause_info (c, inner_type, need_default_ctor,
--- gcc/testsuite/g++.dg/gomp/pr49223-1.C.jj    2011-05-30 13:38:40.000000000 
+0200
+++ gcc/testsuite/g++.dg/gomp/pr49223-1.C       2011-05-30 13:38:08.000000000 
+0200
@@ -0,0 +1,28 @@
+// PR c++/49223
+// { dg-do compile }
+// { dg-options "-fopenmp" }
+
+template <int N>
+struct V
+{
+  V () {}
+  ~V () {}
+};
+
+template <int N>
+struct S
+{
+  void foo ()
+  {
+    V <0> v;
+    #pragma omp parallel private (v)
+      ;
+  }
+};
+
+void
+bar (void)
+{
+  S <0> s;
+  s.foo ();
+}
--- gcc/testsuite/g++.dg/gomp/pr49223-2.C.jj    2011-05-30 13:40:59.000000000 
+0200
+++ gcc/testsuite/g++.dg/gomp/pr49223-2.C       2011-05-30 13:46:05.000000000 
+0200
@@ -0,0 +1,16 @@
+// PR c++/49223
+// { dg-do compile }
+// { dg-require-effective-target tls }
+// { dg-options "-fopenmp" }
+
+struct S;                      // { dg-error "forward declaration" }
+extern __thread struct S s;    // { dg-error "has incomplete type" }
+struct T;
+extern __thread struct T t;
+
+void
+foo ()
+{
+  #pragma omp parallel copyin (s)
+    ;
+}

        Jakub

Reply via email to