Hi!

This changed in OpenMP 4.0 already by mistake and I've kept the 3.1 and
earlier behavior in the hopes that future versions will undo that mistake,
but after discussions it has been determined we are going to keep the 4.0+
behavior.  In most cases it is just about slightly different diagnostics
wording, the most important change is that one can mention the const
qualified vars also in shared clause (previously it could be only mentioned
in firstprivate) and that when using default(none) one has to specify them
if they are referenced (either in firstprivate or shared), otherwise it is
an error.

Tested on x86_64-linux, committed to gomp-5_0-branch.

2018-06-05  Jakub Jelinek  <ja...@redhat.com>

c-family/
        * c-omp.c (c_omp_predetermined_sharing): Don't return
        OMP_CLAUSE_DEFAULT_SHARED for const qualified decls.
c/
        * c-typeck.c (c_finish_omp_clauses): Remove no longer needed special
        case that predetermined const qualified vars may be specified in
        firstprivate clause.  Complain if const qualified vars are mentioned
        in data-sharing clauses other than firstprivate or shared.
cp/
        * cp-gimplify.c (cxx_omp_predetermined_sharing_1): Don't return
        OMP_CLAUSE_DEFAULT_SHARED for const qualified decls with no mutable
        member.  Return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE for this pointer.
        * semantics.c (finish_omp_clauses): Only handle static data members
        in the special case that const qualified vars may be specified in
        firstprivate clause.  Complain if const qualified vars without mutable
        members are mentioned in data-sharing clauses other than firstprivate
        or shared.
testsuite/
        * gcc.dg/gomp/appendix-a/a.24.1.c: Update from OpenMP examples.  Add
        shared(c) clause.
        * gcc.dg/gomp/clause-1.c: Adjust expected diagnostics for const
        qualified vars without mutable member no longer being predeterined
        shared.
        * gcc.dg/gomp/sharing-1.c: Likewise.
        * g++.dg/gomp/clause-3.C: Likewise.
        * g++.dg/gomp/member-2.C: Likewise.
        * g++.dg/gomp/predetermined-1.C: Likewise.
        * g++.dg/gomp/private-1.C: Likewise.
        * g++.dg/gomp/sharing-1.C: Likewise.
        * g++.dg/gomp/sharing-2.C: Likewise.  Add a few tests with aggregate
        const static data member without mutable elements.

--- gcc/c-family/c-omp.c.jj     2018-06-04 18:16:27.197395057 +0200
+++ gcc/c-family/c-omp.c        2018-06-04 19:21:03.361751435 +0200
@@ -1753,11 +1753,6 @@ c_omp_declare_simd_clauses_to_decls (tre
 enum omp_clause_default_kind
 c_omp_predetermined_sharing (tree decl)
 {
-  /* Variables with const-qualified type having no mutable member
-     are predetermined shared.  */
-  if (TREE_READONLY (decl))
-    return OMP_CLAUSE_DEFAULT_SHARED;
-
   /* Predetermine artificial variables holding integral values, those
      are usually result of gimplify_one_sizepos or SAVE_EXPR
      gimplification.  */
--- gcc/c/c-typeck.c.jj 2018-06-04 18:16:29.162398153 +0200
+++ gcc/c/c-typeck.c    2018-06-05 10:59:17.886728884 +0200
@@ -14027,10 +14027,6 @@ c_finish_omp_clauses (tree clauses, enum
                case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
                  break;
                case OMP_CLAUSE_DEFAULT_SHARED:
-                 /* const vars may be specified in firstprivate clause.  */
-                 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
-                     && TREE_READONLY (t))
-                   break;
                  share_name = "shared";
                  break;
                case OMP_CLAUSE_DEFAULT_PRIVATE:
@@ -14047,6 +14043,15 @@ c_finish_omp_clauses (tree clauses, enum
                            omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
                  remove = true;
                }
+             else if (TREE_READONLY (t)
+                      && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
+                      && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
+               {
+                 error_at (OMP_CLAUSE_LOCATION (c),
+                           "%<const%> qualified %qE may appear only in "
+                           "%<shared%> or %<firstprivate%> clauses", t);
+                 remove = true;
+               }
            }
        }
 
--- gcc/cp/cp-gimplify.c.jj     2018-06-04 18:17:52.097528948 +0200
+++ gcc/cp/cp-gimplify.c        2018-06-05 13:08:48.859197368 +0200
@@ -1969,10 +1969,10 @@ cxx_omp_predetermined_sharing_1 (tree de
        return OMP_CLAUSE_DEFAULT_SHARED;
     }
 
-  /* Const qualified vars having no mutable member are predetermined
-     shared.  */
-  if (cxx_omp_const_qual_no_mutable (decl))
-    return OMP_CLAUSE_DEFAULT_SHARED;
+  /* this may not be specified in data-sharing clauses, still we need
+     to predetermined it firstprivate.  */
+  if (decl == current_class_ptr)
+    return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
 
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
 }
--- gcc/cp/semantics.c.jj       2018-06-04 18:17:53.857531721 +0200
+++ gcc/cp/semantics.c  2018-06-05 12:23:57.641980730 +0200
@@ -7431,10 +7431,17 @@ finish_omp_clauses (tree clauses, enum c
            case OMP_CLAUSE_DEFAULT_UNSPECIFIED:
              break;
            case OMP_CLAUSE_DEFAULT_SHARED:
-             /* const vars may be specified in firstprivate clause.  */
-             if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+             if (VAR_P (t)
+                 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
+                 && TREE_STATIC (t)
                  && cxx_omp_const_qual_no_mutable (t))
-               break;
+               {
+                 tree ctx = CP_DECL_CONTEXT (t);
+                 /* const qualified static data members without mutable
+                    member may be specified in firstprivate clause.  */
+                 if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
+                   break;
+               }
              share_name = "shared";
              break;
            case OMP_CLAUSE_DEFAULT_PRIVATE:
@@ -7451,6 +7458,16 @@ finish_omp_clauses (tree clauses, enum c
                        omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
              remove = true;
            }
+         else if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SHARED
+                  && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
+                  && cxx_omp_const_qual_no_mutable (t))
+           {
+             error_at (OMP_CLAUSE_LOCATION (c),
+                       "%<const%> qualified %qE without %<mutable%> member "
+                       "may appear only in %<shared%> or %<firstprivate%> "
+                       "clauses", omp_clause_printable_decl (t));
+             remove = true;
+           }
        }
 
       /* We're interested in the base element, not arrays.  */
--- gcc/testsuite/gcc.dg/gomp/appendix-a/a.24.1.c.jj    2018-04-30 
14:00:58.562726640 +0200
+++ gcc/testsuite/gcc.dg/gomp/appendix-a/a.24.1.c       2018-06-05 
11:21:05.389449572 +0200
@@ -10,14 +10,15 @@ a24 (int a)
   const int c = 1;
   int i = 0;
   int l = 0;
-#pragma omp parallel default(none) private(a) shared(z) /* { dg-line 
omp_parallel } */
+#pragma omp parallel default(none) private(a) shared(z, c) /* { dg-line 
omp_parallel } */
   {
     int j = omp_get_num_threads ();
-    /* O.K. - j is declared within parallel region */
-    /* O.K.  -  a is listed in private clause */
-    /*       -  z is listed in shared clause */
+       /* O.K. - j is declared within parallel region */
+    a = z[j]; /* 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 */
+                               /*       -  c has const-qualified type and
+                                             is listed in shared clause */
     z[i] = y;
     /* { dg-error "'i' not specified" "" { target *-*-* } .-1 } */
     /* { dg-error "enclosing 'parallel'" "" { target *-*-* } omp_parallel } */
--- gcc/testsuite/gcc.dg/gomp/clause-1.c.jj     2017-05-04 15:05:34.814844803 
+0200
+++ gcc/testsuite/gcc.dg/gomp/clause-1.c        2018-06-05 11:24:20.217688621 
+0200
@@ -86,18 +86,18 @@ foo (int x)
 #pragma omp p for linear (t) /* { dg-error "predetermined 'threadprivate" } */
   for (i = 0; i < 10; i++)
     ;
-#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 "'const' qualified 'c' may appear only 
in 'shared' or 'firstprivate' clauses" } */
     ;
 #pragma omp p firstprivate (c)
     ;
-#pragma omp p for lastprivate (c) /* { dg-error "predetermined 'shared'" } */
+#pragma omp p for lastprivate (c) /* { dg-error "'const' qualified 'c' may 
appear only in 'shared' or 'firstprivate' clauses" } */
   for (i = 0; i < 10; i++)
     ;
-#pragma omp p reduction (*:c) /* { dg-error "predetermined 'shared'" } */
+#pragma omp p reduction (*:c) /* { dg-error "'const' qualified 'c' may appear 
only in 'shared' or 'firstprivate' clauses" } */
     ;
-#pragma omp p for linear (c) /* { dg-error "predetermined 'shared'" } */
+#pragma omp p for linear (c) /* { dg-error "'const' qualified 'c' may appear 
only in 'shared' or 'firstprivate' clauses" } */
   for (i = 0; i < 10; i++)
     ;
 }
--- gcc/testsuite/gcc.dg/gomp/sharing-1.c.jj    2017-05-04 15:05:34.756845545 
+0200
+++ gcc/testsuite/gcc.dg/gomp/sharing-1.c       2018-06-05 11:22:55.586584675 
+0200
@@ -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/g++.dg/gomp/clause-3.C.jj     2017-05-04 15:05:46.018701388 
+0200
+++ gcc/testsuite/g++.dg/gomp/clause-3.C        2018-06-05 12:17:02.149486652 
+0200
@@ -86,18 +86,18 @@ foo (int x)
 #pragma omp p for linear (t) // { dg-error "predetermined 'threadprivate'" }
   for (i = 0; i < 10; i++)
     ;
-#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 "may appear only in 'shared' or 
'firstprivate' clauses" }
     ;
 #pragma omp p firstprivate (c)
     ;
-#pragma omp p for lastprivate (c) // { dg-error "predetermined 'shared'" }
+#pragma omp p for lastprivate (c) // { dg-error "may appear only in 'shared' 
or 'firstprivate' clauses" }
   for (i = 0; i < 10; i++)
     ;
-#pragma omp p reduction (*:c) // { dg-error "predetermined 'shared'" }
+#pragma omp p reduction (*:c) // { dg-error "may appear only in 'shared' or 
'firstprivate' clauses" }
     ;
-#pragma omp p for linear (c:2) // { dg-error "predetermined 'shared'" }
+#pragma omp p for linear (c:2) // { dg-error "may appear only in 'shared' or 
'firstprivate' clauses" }
   for (i = 0; i < 10; i++)
     ;
 }
--- gcc/testsuite/g++.dg/gomp/member-2.C.jj     2017-05-04 15:05:46.018701388 
+0200
+++ gcc/testsuite/g++.dg/gomp/member-2.C        2018-06-05 11:38:35.213743917 
+0200
@@ -60,17 +60,17 @@ B::m1 ()
 int
 B::m2 ()
 {
-  #pragma omp parallel private (h)     // { dg-error "is predetermined 
.shared. for .private." }
+  #pragma omp parallel private (h)     // { dg-error "may appear only in 
.shared. or .firstprivate. clauses" }
     ;
   #pragma omp parallel firstprivate (h)
     ;
-  #pragma omp parallel for lastprivate (h)     // { dg-error "is predetermined 
.shared. for .lastprivate." }
+  #pragma omp parallel for lastprivate (h)     // { dg-error "may appear only 
in .shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
-  #pragma omp simd linear (h : 1)      // { dg-error "is predetermined 
.shared. for .linear." }
+  #pragma omp simd linear (h : 1)      // { dg-error "may appear only in 
.shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
-  #pragma omp parallel for reduction (+:h)     // { dg-error "is predetermined 
.shared. for .reduction." }
+  #pragma omp parallel for reduction (+:h)     // { dg-error "may appear only 
in .shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
   #pragma omp parallel for reduction (+:g)     // { dg-error "has const type 
for .reduction." }
@@ -88,7 +88,7 @@ B::m2 ()
     ;
   #pragma omp parallel shared (g)
     ;
-  #pragma omp parallel shared (h)      // { dg-error "is predetermined 
.shared. for .shared." }
+  #pragma omp parallel shared (h)
     ;
   return 0;
 }
@@ -118,30 +118,30 @@ B::m3 () const
 int
 B::m4 () const
 {
-  #pragma omp parallel private (a)     // { dg-error "is predetermined 
.shared. for .private." }
+  #pragma omp parallel private (a)     // { dg-error "may appear only in 
.shared. or .firstprivate. clauses" }
     ;
   #pragma omp parallel firstprivate (a)
     ;
-  #pragma omp parallel for lastprivate (a)     // { dg-error "is predetermined 
.shared. for .lastprivate." }
+  #pragma omp parallel for lastprivate (a)     // { dg-error "may appear only 
in .shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
-  #pragma omp simd linear (a : 1)      // { dg-error "is predetermined 
.shared. for .linear." }
+  #pragma omp simd linear (a : 1)      // { dg-error "may appear only in 
.shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
-  #pragma omp parallel for reduction (+:a)     // { dg-error "is predetermined 
.shared. for .reduction." }
+  #pragma omp parallel for reduction (+:a)     // { dg-error "may appear only 
in .shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
-  #pragma omp parallel private (h)     // { dg-error "is predetermined 
.shared. for .private." }
+  #pragma omp parallel private (h)     // { dg-error "may appear only in 
.shared. or .firstprivate. clauses" }
     ;
   #pragma omp parallel firstprivate (h)
     ;
-  #pragma omp parallel for lastprivate (h)     // { dg-error "is predetermined 
.shared. for .lastprivate." }
+  #pragma omp parallel for lastprivate (h)     // { dg-error "may appear only 
in .shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
-  #pragma omp simd linear (h : 1)      // { dg-error "is predetermined 
.shared. for .linear." }
+  #pragma omp simd linear (h : 1)      // { dg-error "may appear only in 
.shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
-  #pragma omp parallel for reduction (+:h)     // { dg-error "is predetermined 
.shared. for .reduction." }
+  #pragma omp parallel for reduction (+:h)     // { dg-error "may appear only 
in .shared. or .firstprivate. clauses" }
     for (int i = 0; i < 10; i++)
       ;
   #pragma omp parallel for reduction (+:e)     // { dg-error "has const type 
for .reduction." }
@@ -150,7 +150,7 @@ B::m4 () const
   #pragma omp parallel for reduction (+:g)     // { dg-error "has const type 
for .reduction." }
     for (int i = 0; i < 10; i++)
       ;
-  #pragma omp parallel shared (a)      // { dg-error "is predetermined 
.shared. for .shared." }
+  #pragma omp parallel shared (a)
     ;
   #pragma omp parallel shared (b)
     ;
@@ -162,7 +162,7 @@ B::m4 () const
     ;
   #pragma omp parallel shared (g)
     ;
-  #pragma omp parallel shared (h)      // { dg-error "is predetermined 
.shared. for .shared." }
+  #pragma omp parallel shared (h)
     ;
   return 0;
 }
--- gcc/testsuite/g++.dg/gomp/predetermined-1.C.jj      2017-05-04 
15:05:46.019701375 +0200
+++ gcc/testsuite/g++.dg/gomp/predetermined-1.C 2018-06-05 11:40:48.200908057 
+0200
@@ -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;
--- gcc/testsuite/g++.dg/gomp/private-1.C.jj    2017-05-04 15:05:46.053700940 
+0200
+++ gcc/testsuite/g++.dg/gomp/private-1.C       2018-06-05 11:51:22.272675177 
+0200
@@ -15,17 +15,17 @@ 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 "predetermined" }
+  #pragma omp parallel private (a)     // { dg-error "may appear only in 
'shared' or 'firstprivate' clauses" }
     bar (&a);
-  #pragma omp parallel private (b)     // { dg-error "predetermined" }
+  #pragma omp parallel private (b)     // { dg-error "may appear only in 
'shared' or 'firstprivate' clauses" }
     bar (&b);
   #pragma omp parallel private (c)
     bar (&c);
-  #pragma omp parallel private (d)     // { dg-error "predetermined" }
+  #pragma omp parallel private (d)     // { dg-error "may appear only in 
'shared' or 'firstprivate' clauses" }
     bar (&d);
   #pragma omp parallel private (e)
     bar (&e);
-  #pragma omp parallel private (f)     // { dg-error "predetermined" }
+  #pragma omp parallel private (f)     // { dg-error "may appear only in 
'shared' or 'firstprivate' clauses" }
     bar (&f);
   #pragma omp parallel private (g)
     bar (&g);
--- gcc/testsuite/g++.dg/gomp/sharing-1.C.jj    2017-05-04 15:05:46.020701362 
+0200
+++ gcc/testsuite/g++.dg/gomp/sharing-1.C       2018-06-05 11:51:59.184719792 
+0200
@@ -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/sharing-2.C.jj    2017-05-04 15:05:46.030701234 
+0200
+++ gcc/testsuite/g++.dg/gomp/sharing-2.C       2018-06-05 12:36:42.720890595 
+0200
@@ -5,15 +5,21 @@ struct T
   int i;
   mutable int j;
 };
+struct U
+{
+  int i, j;
+};
 struct S
 {
   const static int d = 1;
   const static T e;
+  const static U f;
   void foo (int, T);
 };
 
 const int S::d;
 const T S::e = { 2, 3 };
+const U S::f = { 4, 5 };
 
 void bar (const int &);
 
@@ -28,15 +34,19 @@ S::foo (const int x, const T y)
     bar (y.i);
   #pragma omp parallel firstprivate (e)        // { dg-error "is 
predetermined" }
     bar (e.i);
-  #pragma omp parallel shared (x)      // { dg-error "is predetermined" }
+  #pragma omp parallel firstprivate (f)
+    bar (f.i);
+  #pragma omp parallel shared (x)
     bar (x);
   #pragma omp parallel shared (d)      // { dg-error "is predetermined" }
     bar (d);
   #pragma omp parallel shared (e)      // { dg-error "is predetermined" }
     bar (e.i);
+  #pragma omp parallel shared (f)      // { dg-error "is predetermined" }
+    bar (f.i);
   #pragma omp parallel shared (y)
     bar (y.i);
-  #pragma omp parallel private (x)     // { dg-error "is predetermined" }
+  #pragma omp parallel private (x)     // { dg-error "may appear only in 
'shared' or 'firstprivate' clauses" }
     bar (x);
   #pragma omp parallel private (d)     // { dg-error "is predetermined" }
     bar (d);
@@ -44,4 +54,6 @@ S::foo (const int x, const T y)
     bar (y.i);
   #pragma omp parallel private (e)     // { dg-error "is predetermined" }
     bar (e.i);
+  #pragma omp parallel private (f)     // { dg-error "is predetermined" }
+    bar (f.i);
 }

        Jakub

Reply via email to