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