@@ -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,
@@ -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 ();
+}
@@ -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)
+ ;
+}