@@ -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;
}
@@ -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
@@ -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" }
@@ -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
@@ -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