[gomp5] const qualified vars no longer predetermined shared

Message ID 20180605121049.GB14160@tucnak
State New
Headers show
Series
  • [gomp5] const qualified vars no longer predetermined shared
Related show

Commit Message

Jakub Jelinek June 5, 2018, 12:10 p.m.
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  <jakub@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.


	Jakub

Patch

--- 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);
 }