On Tue, Jun 02, 2015 at 07:35:15PM +0200, Jakub Jelinek wrote:
> I've only noticed now that reduction clause isn't covered in the tests, will
> add that tomorrow.

Here it is:

2015-06-03  Jakub Jelinek  <ja...@redhat.com>

        * semantics.c (omp_clause_printable_decl): New function.
        (finish_omp_reduction_clause, finish_omp_clauses): Use it.
gcc/testsuite/
        * g++.dg/gomp/member-1.C (S::foo, V::foo): Add tests
        for reductions.
        * g++.dg/gomp/member-2.C (struct A): Add another constructor.
        Add #pragma omp declare reduction.
        (foo): New declaration.
        (B::m1, B::m2, B::m3, B::m4): Add tests for reductions.
libgomp/
        * testsuite/libgomp.c++/member-1.C (A::m1): Add tests for
        reductions.
        * testsuite/libgomp.c++/member-2.C (A<Q>::m1): Likewise.

--- gcc/cp/semantics.c.jj       2015-06-02 18:36:34.000000000 +0200
+++ gcc/cp/semantics.c  2015-06-03 10:21:14.430423421 +0200
@@ -5107,6 +5107,30 @@ find_omp_placeholder_r (tree *tp, int *,
   return NULL_TREE;
 }
 
+/* Adjust DECL if needed for printing using %qE.  */
+
+static tree
+omp_clause_printable_decl (tree decl)
+{
+  if (VAR_P (decl)
+      && DECL_HAS_VALUE_EXPR_P (decl)
+      && DECL_ARTIFICIAL (decl)
+      && DECL_LANG_SPECIFIC (decl)
+      && DECL_OMP_PRIVATIZED_MEMBER (decl))
+    {
+      tree f = DECL_VALUE_EXPR (decl);
+      if (TREE_CODE (f) == INDIRECT_REF)
+       f = TREE_OPERAND (f, 0);
+      if (TREE_CODE (f) == COMPONENT_REF)
+       {
+         f = TREE_OPERAND (f, 1);
+         gcc_assert (TREE_CODE (f) == FIELD_DECL);
+         return f;
+       }
+    }
+  return decl;
+}
+
 /* Helper function of finish_omp_clauses.  Handle OMP_CLAUSE_REDUCTION C.
    Return true if there is some error and the clause should be removed.  */
 
@@ -5152,7 +5176,8 @@ finish_omp_reduction_clause (tree c, boo
       }
   else if (TREE_CODE (type) == ARRAY_TYPE || TYPE_READONLY (type))
     {
-      error ("%qE has invalid type for %<reduction%>", t);
+      error ("%qE has invalid type for %<reduction%>",
+            omp_clause_printable_decl (t));
       return true;
     }
   else if (!processing_template_decl)
@@ -5300,7 +5325,8 @@ finish_omp_reduction_clause (tree c, boo
     *need_dtor = true;
   else
     {
-      error ("user defined reduction not found for %qD", t);
+      error ("user defined reduction not found for %qE",
+            omp_clause_printable_decl (t));
       return true;
     }
   return false;
@@ -6247,24 +6273,8 @@ finish_omp_clauses (tree clauses, bool a
            }
          if (share_name)
            {
-             tree pt = t;
-             if (VAR_P (t)
-                 && DECL_HAS_VALUE_EXPR_P (t)
-                 && DECL_ARTIFICIAL (t)
-                 && DECL_LANG_SPECIFIC (t)
-                 && DECL_OMP_PRIVATIZED_MEMBER (t))
-               {
-                 tree f = DECL_VALUE_EXPR (t);
-                 if (TREE_CODE (f) == INDIRECT_REF)
-                   f = TREE_OPERAND (f, 0);
-                 if (TREE_CODE (f) == COMPONENT_REF)
-                   {
-                     f = TREE_OPERAND (f, 1);
-                     gcc_assert (TREE_CODE (f) == FIELD_DECL);
-                     pt = f;
-                   }
-               }
-             error ("%qE is predetermined %qs for %qs", pt, share_name,
+             error ("%qE is predetermined %qs for %qs",
+                    omp_clause_printable_decl (t), share_name,
                     omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
              remove = true;
            }
--- gcc/testsuite/g++.dg/gomp/member-1.C.jj     2015-06-01 12:44:20.000000000 
+0200
+++ gcc/testsuite/g++.dg/gomp/member-1.C        2015-06-03 10:34:37.508180173 
+0200
@@ -103,6 +103,25 @@ S::foo ()
 #pragma omp taskloop firstprivate (a, t) lastprivate (t)
   for (int i = 0; i < a; i++)
     t++;
+  a = 1;
+  t = 0;
+#pragma omp parallel sections reduction (*: S::a) reduction (+: t)
+  {
+    {
+      a = 1;
+      t = 2;
+    }
+    #pragma omp section
+    {
+      a = 2;
+      t = 3;
+    }
+    #pragma omp section
+    {
+      a = 3;
+      t = 4;
+    }
+  }
 }
 
 template <typename T>
@@ -204,6 +223,25 @@ V<T>::foo ()
 #pragma omp taskloop firstprivate (a, U<T>::t) lastprivate (U<T>::t)
   for (int i = 0; i < a; i++)
     U<T>::t++;
+  a = 1;
+  U<T>::t = 0;
+#pragma omp parallel sections reduction (*: V::a) reduction (+: U<T>::t)
+  {
+    {
+      a = 1;
+      U<T>::t = 2;
+    }
+    #pragma omp section
+    {
+      a = 2;
+      U<T>::t = 3;
+    }
+    #pragma omp section
+    {
+      a = 3;
+      U<T>::t = 4;
+    }
+  }
 }
 
 void
--- gcc/testsuite/g++.dg/gomp/member-2.C.jj     2015-06-02 17:46:48.000000000 
+0200
+++ gcc/testsuite/g++.dg/gomp/member-2.C        2015-06-03 10:24:35.000000000 
+0200
@@ -6,6 +6,7 @@ int d;
 struct A
 {
   A () : a(2), b(3), c(d) {}
+  A (int x) : a(2), b(x), c(d) {}
   int a;
   A (const A &);
   A &operator= (const A &);
@@ -29,6 +30,10 @@ struct B : public A
   int m4 () const;
 };
 
+void foo (A &);
+
+#pragma omp declare reduction (+:A:omp_out.b += omp_in.b) initializer (foo 
(omp_priv))
+
 int
 B::m1 ()
 {
@@ -46,6 +51,9 @@ B::m1 ()
        b++;
        c++;
       }
+  #pragma omp parallel for reduction (+:a, b, c, e, f)
+    for (int i = 0; i < 10; i++)
+      ;
   return 0;
 }
 
@@ -62,6 +70,12 @@ B::m2 ()
   #pragma omp simd linear (h : 1)      // { dg-error "is predetermined 
.shared. for .linear." }
     for (int i = 0; i < 10; i++)
       ;
+  #pragma omp parallel for reduction (+:h)     // { dg-error "is predetermined 
.shared. for .reduction." }
+    for (int i = 0; i < 10; i++)
+      ;
+  #pragma omp parallel for reduction (+:g)     // { dg-error "has invalid type 
for .reduction." }
+    for (int i = 0; i < 10; i++)
+      ;
   #pragma omp parallel shared (a)      // { dg-error "is not a variable in 
clause" }
     ;
   #pragma omp parallel shared (b)      // { dg-error "is not a variable in 
clause" }
@@ -95,6 +109,9 @@ B::m3 () const
        b++;
        c++;
       }
+  #pragma omp parallel for reduction (+:b, c, f)
+    for (int i = 0; i < 10; i++)
+      ;
   return 0;
 }
 
@@ -111,6 +128,9 @@ B::m4 () const
   #pragma omp simd linear (a : 1)      // { dg-error "is predetermined 
.shared. for .linear." }
     for (int i = 0; i < 10; i++)
       ;
+  #pragma omp parallel for reduction (+:a)     // { dg-error "is predetermined 
.shared. for .reduction." }
+    for (int i = 0; i < 10; i++)
+      ;
   #pragma omp parallel private (h)     // { dg-error "is predetermined 
.shared. for .private." }
     ;
   #pragma omp parallel firstprivate (h)
@@ -121,6 +141,15 @@ B::m4 () const
   #pragma omp simd linear (h : 1)      // { dg-error "is predetermined 
.shared. for .linear." }
     for (int i = 0; i < 10; i++)
       ;
+  #pragma omp parallel for reduction (+:h)     // { dg-error "is predetermined 
.shared. for .reduction." }
+    for (int i = 0; i < 10; i++)
+      ;
+  #pragma omp parallel for reduction (+:e)     // { dg-error "has invalid type 
for .reduction." }
+    for (int i = 0; i < 10; i++)
+      ;
+  #pragma omp parallel for reduction (+:g)     // { dg-error "has invalid type 
for .reduction." }
+    for (int i = 0; i < 10; i++)
+      ;
   #pragma omp parallel shared (a)      // { dg-error "is not a variable in 
clause" }
     ;
   #pragma omp parallel shared (b)      // { dg-error "is not a variable in 
clause" }
--- libgomp/testsuite/libgomp.c++/member-1.C.jj 2015-06-02 14:53:42.000000000 
+0200
+++ libgomp/testsuite/libgomp.c++/member-1.C    2015-06-03 09:45:48.880851120 
+0200
@@ -182,6 +182,21 @@ A::m1 ()
       if (a != n || b != 2 * n || r != 3 * n || t != 4 * n)
        __builtin_abort ();
     }
+  a = 0;
+  b = 0;
+  R::r = 0;
+  t = 0;
+  #pragma omp parallel for reduction (+: A::a, t, b, R::r)
+  for (int i = 0; i < 30; i++)
+    {
+      a += i;
+      A::b += 2 * i;
+      r += 3 * i;
+      T::t += 4 * i;
+      take (a, b, r, t);
+    }
+  if (A::a != 435 || b != 2 * 435 || R::r != 3 * 435 || t != 4 * 435)
+    __builtin_abort ();
 }
 
 int
--- libgomp/testsuite/libgomp.c++/member-2.C.jj 2015-06-02 18:00:58.000000000 
+0200
+++ libgomp/testsuite/libgomp.c++/member-2.C    2015-06-03 09:46:46.993960724 
+0200
@@ -185,6 +185,21 @@ A<Q>::m1 ()
       if (a != n || b != 2 * n || r != 3 * n || T<Q>::t != 4 * n)
        __builtin_abort ();
     }
+  a = 0;
+  b = 0;
+  R::r = 0;
+  T<Q>::t = 0;
+  #pragma omp parallel for reduction (+: A::a, T<Q>::t, b, R::r)
+  for (int i = 0; i < 30; i++)
+    {
+      a += i;
+      A::b += 2 * i;
+      r += 3 * i;
+      T<Q>::t += 4 * i;
+      take (a, b, r, T<Q>::t);
+    }
+  if (A::a != 435 || b != 2 * 435 || R::r != 3 * 435 || T<Q>::t != 4 * 435)
+    __builtin_abort ();
 }
 
 int


        Jakub

Reply via email to