openmp: Assorted depend/affinity/iterator related fixes [PR100859]
The depend-iterator-3.C testcases shows various bugs. 1) tsubst_omp_clauses didn't handle OMP_CLAUSE_AFFINITY (should be handled like OMP_CLAUSE_DEPEND) 2) because locators can be arbitrary lvalue expressions, we need to allow for C++ array section base (especially when array section is just an array reference) FIELD_DECLs, handle them as this->member, but don't need to privatize in any way 3) similarly for this as base 4) depend(inout: this) is invalid, but for different reason than the reported one, again this is an expression, but not lvalue expression, so that should be reported 5) the ctor/dtor cloning in the C++ FE (which is using walk_tree with copy_tree_body_r) didn't handle iterators correctly, walk_tree normally doesn't walk TREE_PURPOSE of TREE_LIST, and in the iterator case that TREE_VEC contains also a BLOCK that needs special handling during copy_tree_body_r 2021-06-03 Jakub Jelinek <jakub@redhat.com> PR c++/100859 gcc/ * tree-inline.c (copy_tree_body_r): Handle iterators on OMP_CLAUSE_AFFINITY or OMP_CLAUSE_DEPEND. gcc/c/ * c-typeck.c (c_finish_omp_clauses): Move OMP_CLAUSE_AFFINITY after depend only cases. gcc/cp/ * semantics.c (handle_omp_array_sections_1): For OMP_CLAUSE_{AFFINITY,DEPEND} handle FIELD_DECL base using finish_non_static_data_member and allow this as base. (finish_omp_clauses): Move OMP_CLAUSE_AFFINITY after depend only cases. Let this be diagnosed by !lvalue_p case for OMP_CLAUSE_{AFFINITY,DEPEND} and remove useless assert. * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_AFFINITY. gcc/testsuite/ * g++.dg/gomp/depend-iterator-3.C: New test. * g++.dg/gomp/this-1.C: Don't expect any diagnostics for this as base expression of depend array section, expect a different error wording for this as depend locator and add testcases for affinity clauses.
This commit is contained in:
parent
bff9a7ec6e
commit
098f4e989b
|
@ -14557,7 +14557,6 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
}
|
||||
break;
|
||||
|
||||
case OMP_CLAUSE_AFFINITY:
|
||||
case OMP_CLAUSE_DEPEND:
|
||||
t = OMP_CLAUSE_DECL (c);
|
||||
if (t == NULL_TREE)
|
||||
|
@ -14566,8 +14565,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
== OMP_CLAUSE_DEPEND_SOURCE);
|
||||
break;
|
||||
}
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
|
||||
&& OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
|
||||
if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
|
||||
{
|
||||
gcc_assert (TREE_CODE (t) == TREE_LIST);
|
||||
for (; t; t = TREE_CHAIN (t))
|
||||
|
@ -14595,6 +14593,9 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
}
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case OMP_CLAUSE_AFFINITY:
|
||||
t = OMP_CLAUSE_DECL (c);
|
||||
if (TREE_CODE (t) == TREE_LIST
|
||||
&& TREE_PURPOSE (t)
|
||||
&& TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
|
||||
|
|
|
@ -17399,6 +17399,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
|
|||
case OMP_CLAUSE_COPYPRIVATE:
|
||||
case OMP_CLAUSE_UNIFORM:
|
||||
case OMP_CLAUSE_DEPEND:
|
||||
case OMP_CLAUSE_AFFINITY:
|
||||
case OMP_CLAUSE_FROM:
|
||||
case OMP_CLAUSE_TO:
|
||||
case OMP_CLAUSE_MAP:
|
||||
|
|
|
@ -4968,7 +4968,11 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
|
|||
if (REFERENCE_REF_P (t))
|
||||
t = TREE_OPERAND (t, 0);
|
||||
}
|
||||
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
|
||||
if (TREE_CODE (t) == FIELD_DECL
|
||||
&& (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY
|
||||
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND))
|
||||
ret = finish_non_static_data_member (t, NULL_TREE, NULL_TREE);
|
||||
else if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
|
||||
{
|
||||
if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
|
||||
return NULL_TREE;
|
||||
|
@ -4985,7 +4989,9 @@ handle_omp_array_sections_1 (tree c, tree t, vec<tree> &types,
|
|||
else if (ort == C_ORT_OMP
|
||||
&& TREE_CODE (t) == PARM_DECL
|
||||
&& DECL_ARTIFICIAL (t)
|
||||
&& DECL_NAME (t) == this_identifier)
|
||||
&& DECL_NAME (t) == this_identifier
|
||||
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_AFFINITY
|
||||
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_DEPEND)
|
||||
{
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<this%> allowed in OpenMP only in %<declare simd%>"
|
||||
|
@ -7468,7 +7474,6 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
}
|
||||
goto handle_field_decl;
|
||||
|
||||
case OMP_CLAUSE_AFFINITY:
|
||||
case OMP_CLAUSE_DEPEND:
|
||||
t = OMP_CLAUSE_DECL (c);
|
||||
if (t == NULL_TREE)
|
||||
|
@ -7477,13 +7482,15 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
== OMP_CLAUSE_DEPEND_SOURCE);
|
||||
break;
|
||||
}
|
||||
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
|
||||
&& OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
|
||||
if (OMP_CLAUSE_DEPEND_KIND (c) == OMP_CLAUSE_DEPEND_SINK)
|
||||
{
|
||||
if (cp_finish_omp_clause_depend_sink (c))
|
||||
remove = true;
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case OMP_CLAUSE_AFFINITY:
|
||||
t = OMP_CLAUSE_DECL (c);
|
||||
if (TREE_CODE (t) == TREE_LIST
|
||||
&& TREE_PURPOSE (t)
|
||||
&& TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
|
||||
|
@ -7516,13 +7523,6 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
}
|
||||
if (t == error_mark_node)
|
||||
remove = true;
|
||||
else if (ort != C_ORT_ACC && t == current_class_ptr)
|
||||
{
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"%<this%> allowed in OpenMP only in %<declare simd%>"
|
||||
" clauses");
|
||||
remove = true;
|
||||
}
|
||||
else if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
|
||||
break;
|
||||
else if (!lvalue_p (t))
|
||||
|
@ -7543,11 +7543,9 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
|
|||
&& TREE_CODE (TREE_OPERAND (t, 1)) == FIELD_DECL
|
||||
&& DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
|
||||
{
|
||||
gcc_assert (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
|
||||
|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_AFFINITY);
|
||||
error_at (OMP_CLAUSE_LOCATION (c),
|
||||
"bit-field %qE in %qs clause", t,
|
||||
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
|
||||
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
|
||||
remove = true;
|
||||
}
|
||||
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
// PR c++/100859
|
||||
|
||||
struct S {
|
||||
S () {}
|
||||
};
|
||||
|
||||
struct W {
|
||||
S c[10];
|
||||
W () {
|
||||
#pragma omp task affinity (iterator (i = 0 : 10 : 1): c[i])
|
||||
;
|
||||
#pragma omp task depend (iterator (i = 0 : 10 : 1), inout: c[i])
|
||||
;
|
||||
#pragma omp task affinity (this[0])
|
||||
;
|
||||
#pragma omp task depend (inout: this[0])
|
||||
;
|
||||
#pragma omp taskwait
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct U {
|
||||
T c[10];
|
||||
U () {
|
||||
#pragma omp task affinity (iterator (i = 0 : 10 : 1): c[i])
|
||||
;
|
||||
#pragma omp task depend (iterator (i = 0 : 10 : 1), inout: c[i])
|
||||
;
|
||||
#pragma omp task affinity (this[0])
|
||||
;
|
||||
#pragma omp task depend (inout: this[0])
|
||||
;
|
||||
#pragma omp taskwait
|
||||
}
|
||||
};
|
||||
|
||||
struct V : public U<S> {
|
||||
V () : U<S> () {}
|
||||
};
|
||||
|
||||
W w;
|
||||
V v;
|
|
@ -21,9 +21,13 @@ S::bar ()
|
|||
#pragma omp for linear (this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
|
||||
for (int i = 0; i < 10; i++)
|
||||
;
|
||||
#pragma omp task depend(inout: this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
|
||||
#pragma omp task depend(inout: this) // { dg-error ".this. is not lvalue expression nor array section in .depend. clause" }
|
||||
;
|
||||
#pragma omp task depend(inout: this[0]) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
|
||||
#pragma omp task depend(inout: this[0])
|
||||
;
|
||||
#pragma omp task affinity(this) // { dg-error ".this. is not lvalue expression nor array section in .affinity. clause" }
|
||||
;
|
||||
#pragma omp task affinity(this[0])
|
||||
;
|
||||
#pragma omp parallel private (this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
|
||||
{
|
||||
|
@ -54,9 +58,13 @@ T<N>::bar ()
|
|||
#pragma omp for linear (this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
|
||||
for (int i = 0; i < 10; i++)
|
||||
;
|
||||
#pragma omp task depend(inout: this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
|
||||
#pragma omp task depend(inout: this) // { dg-error ".this. is not lvalue expression nor array section in .depend. clause" }
|
||||
;
|
||||
#pragma omp task depend(inout: this[0]) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
|
||||
#pragma omp task depend(inout: this[0])
|
||||
;
|
||||
#pragma omp task affinity(this) // { dg-error ".this. is not lvalue expression nor array section in .affinity. clause" }
|
||||
;
|
||||
#pragma omp task affinity(this[0])
|
||||
;
|
||||
#pragma omp parallel private (this) // { dg-error ".this. allowed in OpenMP only in .declare simd. clauses" }
|
||||
{
|
||||
|
|
|
@ -1453,6 +1453,27 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
|
|||
|
||||
*walk_subtrees = 0;
|
||||
}
|
||||
else if (TREE_CODE (*tp) == OMP_CLAUSE
|
||||
&& (OMP_CLAUSE_CODE (*tp) == OMP_CLAUSE_AFFINITY
|
||||
|| OMP_CLAUSE_CODE (*tp) == OMP_CLAUSE_DEPEND))
|
||||
{
|
||||
tree t = OMP_CLAUSE_DECL (*tp);
|
||||
if (TREE_CODE (t) == TREE_LIST
|
||||
&& TREE_PURPOSE (t)
|
||||
&& TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC)
|
||||
{
|
||||
*walk_subtrees = 0;
|
||||
OMP_CLAUSE_DECL (*tp) = copy_node (t);
|
||||
t = OMP_CLAUSE_DECL (*tp);
|
||||
TREE_PURPOSE (t) = copy_node (TREE_PURPOSE (t));
|
||||
for (int i = 0; i <= 4; i++)
|
||||
walk_tree (&TREE_VEC_ELT (TREE_PURPOSE (t), i),
|
||||
copy_tree_body_r, id, NULL);
|
||||
if (TREE_VEC_ELT (TREE_PURPOSE (t), 5))
|
||||
remap_block (&TREE_VEC_ELT (TREE_PURPOSE (t), 5), id);
|
||||
walk_tree (&TREE_VALUE (t), copy_tree_body_r, id, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep iterating. */
|
||||
|
|
Loading…
Reference in New Issue