Hi! As %subj. said, const vars are no longer predetermined shared, they are just not allowed in private/lastprivate/reduction clauses.
Tested on x86_64-linux, committed to gomp-3_1-branch. 2011-03-10 Jakub Jelinek <ja...@redhat.com> * c-omp.c (c_omp_predetermined_sharing): Don't return OMP_CLAUSE_DEFAULT_SHARED for TREE_READONLY decls. * c-typeck.c (c_finish_omp_clauses): Complain about TREE_READONLY decls in private, lastprivate and reduction clauses. * cp-gimplify.c (cxx_omp_predetermined_sharing): Don't return OMP_CLAUSE_DEFAULT_SHARED for decls with TYPE_READONLY type having no mutable member. * semantics.c (finish_omp_clauses): Complain about TREE_READONLY decls with no mutable member in private, lastprivate and reduction clauses. * gcc.dg/gomp/appendix-a/a.24.1.c: Adjust for const-qualified decls having no mutable members no longer being predetermined shared. * gcc.dg/gomp/sharing-1.c: Likewise. * gcc.dg/gomp/clause-1.c: Likewise. * g++.dg/gomp/sharing-1.C: Likewise. * g++.dg/gomp/clause-3.C: Likewise. * g++.dg/gomp/predetermined-1.C: Likewise. * g++.dg/gomp/private-1.C: New test. --- gcc/c-family/c-omp.c.jj 2011-03-03 19:59:40.000000000 +0100 +++ gcc/c-family/c-omp.c 2011-03-10 12:04:09.000000000 +0100 @@ -519,12 +519,7 @@ c_split_parallel_clauses (location_t loc /* True if OpenMP sharing attribute of DECL is predetermined. */ enum omp_clause_default_kind -c_omp_predetermined_sharing (tree decl) +c_omp_predetermined_sharing (tree decl ATTRIBUTE_UNUSED) { - /* Variables with const-qualified type having no mutable member - are predetermined shared. */ - if (TREE_READONLY (decl)) - return OMP_CLAUSE_DEFAULT_SHARED; - return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } --- gcc/c-typeck.c.jj 2011-03-03 20:00:38.000000000 +0100 +++ gcc/c-typeck.c 2011-03-10 12:04:09.000000000 +0100 @@ -10406,6 +10406,7 @@ c_finish_omp_clauses (tree clauses) bool remove = false; bool need_complete = false; bool need_implicitly_determined = false; + bool no_const = false; switch (OMP_CLAUSE_CODE (c)) { @@ -10418,11 +10419,13 @@ c_finish_omp_clauses (tree clauses) name = "private"; need_complete = true; need_implicitly_determined = true; + no_const = true; goto check_dup_generic; case OMP_CLAUSE_REDUCTION: name = "reduction"; need_implicitly_determined = true; + no_const = true; t = OMP_CLAUSE_DECL (c); if (AGGREGATE_TYPE_P (TREE_TYPE (t)) || POINTER_TYPE_P (TREE_TYPE (t))) @@ -10534,6 +10537,7 @@ c_finish_omp_clauses (tree clauses) t = OMP_CLAUSE_DECL (c); need_complete = true; need_implicitly_determined = true; + no_const = true; if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL) { error_at (OMP_CLAUSE_LOCATION (c), @@ -10603,6 +10607,13 @@ c_finish_omp_clauses (tree clauses) t, share_name, name); remove = true; } + else if (no_const && TREE_READONLY (t)) + { + error_at (OMP_CLAUSE_LOCATION (c), + "const-qualified %qE cannot appear in %qs clause", + t, name); + remove = true; + } } } --- gcc/cp/cp-gimplify.c.jj 2011-02-24 14:18:07.000000000 +0100 +++ gcc/cp/cp-gimplify.c 2011-03-10 12:04:09.000000000 +0100 @@ -1184,8 +1184,6 @@ cxx_omp_privatize_by_reference (const_tr enum omp_clause_default_kind cxx_omp_predetermined_sharing (tree decl) { - tree type; - /* Static data members are predetermined as shared. */ if (TREE_STATIC (decl)) { @@ -1194,41 +1192,6 @@ cxx_omp_predetermined_sharing (tree decl return OMP_CLAUSE_DEFAULT_SHARED; } - type = TREE_TYPE (decl); - if (TREE_CODE (type) == REFERENCE_TYPE) - { - if (!is_invisiref_parm (decl)) - return OMP_CLAUSE_DEFAULT_UNSPECIFIED; - type = TREE_TYPE (type); - - if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl)) - { - /* NVR doesn't preserve const qualification of the - variable's type. */ - tree outer = outer_curly_brace_block (current_function_decl); - tree var; - - if (outer) - for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var)) - if (DECL_NAME (decl) == DECL_NAME (var) - && (TYPE_MAIN_VARIANT (type) - == TYPE_MAIN_VARIANT (TREE_TYPE (var)))) - { - if (TYPE_READONLY (TREE_TYPE (var))) - type = TREE_TYPE (var); - break; - } - } - } - - if (type == error_mark_node) - return OMP_CLAUSE_DEFAULT_UNSPECIFIED; - - /* Variables with const-qualified type having no mutable member - are predetermined shared. */ - if (TYPE_READONLY (type) && !cp_has_mutable_p (type)) - return OMP_CLAUSE_DEFAULT_SHARED; - return OMP_CLAUSE_DEFAULT_UNSPECIFIED; } --- gcc/cp/semantics.c.jj 2011-03-03 20:00:38.000000000 +0100 +++ gcc/cp/semantics.c 2011-03-10 12:04:09.000000000 +0100 @@ -3820,6 +3820,7 @@ finish_omp_clauses (tree clauses) bool need_copy_ctor = false; bool need_copy_assignment = false; bool need_implicitly_determined = false; + bool no_const = false; tree type, inner_type; switch (c_kind) @@ -3833,6 +3834,7 @@ finish_omp_clauses (tree clauses) need_complete_non_reference = true; need_default_ctor = true; need_implicitly_determined = true; + no_const = true; break; case OMP_CLAUSE_FIRSTPRIVATE: name = "firstprivate"; @@ -3845,10 +3847,12 @@ finish_omp_clauses (tree clauses) need_complete_non_reference = true; need_copy_assignment = true; need_implicitly_determined = true; + no_const = true; break; case OMP_CLAUSE_REDUCTION: name = "reduction"; need_implicitly_determined = true; + no_const = true; break; case OMP_CLAUSE_COPYPRIVATE: name = "copyprivate"; @@ -3952,6 +3956,23 @@ finish_omp_clauses (tree clauses) t, share_name, name); remove = true; } + else if (no_const) + { + type = TREE_TYPE (t); + if (type != error_mark_node + && TYPE_READONLY (type) + && (c_kind == OMP_CLAUSE_REDUCTION + || !cp_has_mutable_p (type))) + { + if (c_kind == OMP_CLAUSE_REDUCTION) + error ("const-qualified %qE cannot appear in " + "%<reduction%> clause", t); + else + error ("const-qualified %qE with no mutable member " + "cannot appear in %qs clause", t, name); + remove = true; + } + } } /* We're interested in the base element, not arrays. */ --- gcc/testsuite/gcc.dg/gomp/appendix-a/a.24.1.c.jj 2011-02-24 14:13:38.000000000 +0100 +++ gcc/testsuite/gcc.dg/gomp/appendix-a/a.24.1.c 2011-03-10 12:58:21.000000000 +0100 @@ -17,7 +17,7 @@ a24 (int a) /* O.K. - a is listed in private clause */ /* - z is listed in shared clause */ x = c; /* O.K. - x is threadprivate */ - /* - c has const-qualified type */ + /* { dg-error "'c' not specified" "" { target *-*-* } 19 } */ z[i] = y; /* { dg-error "'i' not specified" "" { target *-*-* } 21 } */ /* { dg-error "enclosing parallel" "" { target *-*-* } 13 } */ --- gcc/testsuite/gcc.dg/gomp/sharing-1.c.jj 2011-02-24 14:13:38.000000000 +0100 +++ gcc/testsuite/gcc.dg/gomp/sharing-1.c 2011-03-10 13:10:21.000000000 +0100 @@ -44,7 +44,7 @@ main (void) thrglobalvar++; /* Predetermined - threadprivate. */ thrlocvar++; /* Predetermined - threadprivate. */ foo (i); /* Predetermined - private (omp for loop variable). */ - foo (constvar); /* Predetermined - shared (const qualified type). */ + foo (constvar); /* { dg-error "not specified in" } */ foo (*p); /* *p predetermined - shared (heap allocated */ (*p)++; /* storage). */ bar (p); /* Explicitly determined - private. */ --- gcc/testsuite/gcc.dg/gomp/clause-1.c.jj 2011-02-24 14:13:38.000000000 +0100 +++ gcc/testsuite/gcc.dg/gomp/clause-1.c 2011-03-10 13:08:34.000000000 +0100 @@ -80,15 +80,15 @@ foo (int x) ; #pragma omp p reduction (*:t) /* { dg-error "predetermined 'threadprivate" } */ ; -#pragma omp p shared (c) /* { dg-error "predetermined 'shared'" } */ +#pragma omp p shared (c) ; -#pragma omp p private (c) /* { dg-error "predetermined 'shared'" } */ +#pragma omp p private (c) /* { dg-error "cannot appear in 'private'" } */ ; -#pragma omp p firstprivate (c) /* { dg-error "predetermined 'shared'" } */ +#pragma omp p firstprivate (c) ; -#pragma omp p for lastprivate (c) /* { dg-error "predetermined 'shared'" } */ +#pragma omp p for lastprivate (c) /* { dg-error "cannot appear in 'lastprivate'" } */ for (i = 0; i < 10; i++) ; -#pragma omp p reduction (*:c) /* { dg-error "predetermined 'shared'" } */ +#pragma omp p reduction (*:c) /* { dg-error "cannot appear in 'reduction'" } */ ; } --- gcc/testsuite/g++.dg/gomp/private-1.C.jj 2011-03-10 13:42:08.000000000 +0100 +++ gcc/testsuite/g++.dg/gomp/private-1.C 2011-03-10 13:44:38.000000000 +0100 @@ -0,0 +1,33 @@ +// { dg-do compile } +// { dg-options "-fopenmp" } + +struct A { int i; A (); ~A (); }; +struct B { int i; }; +struct C { int i; mutable int j; C (); ~C (); }; + +template <typename T> void bar (const T *); + +const A a; +const C c; + +const A foo (const A d, const C e) +{ + const A f; + const B b = { 4 }; + A g; + #pragma omp parallel private (a) // { dg-error "cannot appear in 'private'" } + bar (&a); + #pragma omp parallel private (b) // { dg-error "cannot appear in 'private'" } + bar (&b); + #pragma omp parallel private (c) + bar (&c); + #pragma omp parallel private (d) // { dg-error "cannot appear in 'private'" } + bar (&d); + #pragma omp parallel private (e) + bar (&e); + #pragma omp parallel private (f) // { dg-error "cannot appear in 'private'" } + bar (&f); + #pragma omp parallel private (g) + bar (&g); + return f; +} --- gcc/testsuite/g++.dg/gomp/sharing-1.C.jj 2011-02-24 14:16:31.000000000 +0100 +++ gcc/testsuite/g++.dg/gomp/sharing-1.C 2011-03-10 13:10:50.000000000 +0100 @@ -61,7 +61,7 @@ main (void) thrglobalvar++; /* Predetermined - threadprivate. */ thrlocvar++; /* Predetermined - threadprivate. */ foo (i); /* Predetermined - private (omp for loop variable). */ - foo (constvar.x); /* Predetermined - shared (const qualified type). */ + foo (constvar.x); /* { dg-error "not specified in" } */ foo (T::t.i); /* Predetermined - shared (static data member). */ foo (*p); /* *p predetermined - shared (heap allocated */ (*p)++; /* storage). */ --- gcc/testsuite/g++.dg/gomp/clause-3.C.jj 2011-02-24 14:16:31.000000000 +0100 +++ gcc/testsuite/g++.dg/gomp/clause-3.C 2011-03-10 13:40:11.000000000 +0100 @@ -80,15 +80,15 @@ foo (int x) ; #pragma omp p reduction (*:t) // { dg-error "predetermined 'threadprivate'" } ; -#pragma omp p shared (c) // { dg-error "predetermined 'shared'" } +#pragma omp p shared (c) ; -#pragma omp p private (c) // { dg-error "predetermined 'shared'" } +#pragma omp p private (c) // { dg-error "cannot appear in 'private'" } ; -#pragma omp p firstprivate (c) // { dg-error "predetermined 'shared'" } +#pragma omp p firstprivate (c) ; -#pragma omp p for lastprivate (c) // { dg-error "predetermined 'shared'" } +#pragma omp p for lastprivate (c) // { dg-error "cannot appear in 'lastprivate'" } for (i = 0; i < 10; i++) ; -#pragma omp p reduction (*:c) // { dg-error "predetermined 'shared'" } +#pragma omp p reduction (*:c) // { dg-error "cannot appear in 'reduction'" } ; } --- gcc/testsuite/g++.dg/gomp/predetermined-1.C.jj 2011-02-24 14:16:31.000000000 +0100 +++ gcc/testsuite/g++.dg/gomp/predetermined-1.C 2011-03-10 13:41:35.000000000 +0100 @@ -15,18 +15,18 @@ const A foo (const A d, const C e) const A f; const B b = { 4 }; A g; - #pragma omp parallel default (none) - bar (&a); - #pragma omp parallel default (none) - bar (&b); + #pragma omp parallel default (none) // { dg-error "enclosing parallel" } + bar (&a); // { dg-error "not specified" } + #pragma omp parallel default (none) // { dg-error "enclosing parallel" } + bar (&b); // { dg-error "not specified" } #pragma omp parallel default (none) // { dg-error "enclosing parallel" } bar (&c); // { dg-error "not specified" } - #pragma omp parallel default (none) - bar (&d); + #pragma omp parallel default (none) // { dg-error "enclosing parallel" } + bar (&d); // { dg-error "not specified" } #pragma omp parallel default (none) // { dg-error "enclosing parallel" } bar (&e); // { dg-error "not specified" } - #pragma omp parallel default (none) - bar (&f); + #pragma omp parallel default (none) // { dg-error "enclosing parallel" } + bar (&f); // { dg-error "not specified" } #pragma omp parallel default (none) // { dg-error "enclosing parallel" } bar (&g); // { dg-error "not specified" } return f; Jakub