@@ -1234,8 +1234,8 @@ extern void c_finish_omp_taskyield (loca
extern tree c_finish_omp_for (location_t, enum tree_code, tree, tree, tree,
tree, tree, tree, tree, bool);
extern bool c_omp_check_loop_iv (tree, tree, walk_tree_lh);
-extern bool c_omp_check_loop_iv_exprs (location_t, tree, int, tree, tree, tree,
- walk_tree_lh);
+extern bool c_omp_check_loop_iv_exprs (location_t, enum tree_code, tree, int,
+ tree, tree, tree, walk_tree_lh);
extern tree c_finish_oacc_wait (location_t, tree, tree);
extern tree c_oacc_split_loop_clauses (tree, tree *, bool);
extern void c_omp_split_clauses (location_t, enum tree_code, omp_clause_mask,
@@ -1353,6 +1353,19 @@ c_omp_check_loop_iv_r (tree *tp, int *wa
}
d->fail = true;
}
+ else if ((d->kind & 4)
+ && TREE_CODE (*tp) != TREE_VEC
+ && TREE_CODE (*tp) != PLUS_EXPR
+ && TREE_CODE (*tp) != MINUS_EXPR
+ && TREE_CODE (*tp) != MULT_EXPR
+ && !CONVERT_EXPR_P (*tp))
+ {
+ *walk_subtrees = 0;
+ d->kind &= 3;
+ walk_tree_1 (tp, c_omp_check_loop_iv_r, data, NULL, d->lh);
+ d->kind |= 4;
+ return NULL_TREE;
+ }
else if (d->ppset->add (*tp))
*walk_subtrees = 0;
/* Don't walk dtors added by C++ wrap_cleanups_r. */
@@ -1651,11 +1677,13 @@ c_omp_check_loop_iv (tree stmt, tree dec
/* Similar, but allows to check the init or cond expressions individually. */
bool
-c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, int i, tree decl,
- tree init, tree cond, walk_tree_lh lh)
+c_omp_check_loop_iv_exprs (location_t stmt_loc, enum tree_code code,
+ tree declv, int i, tree decl, tree init, tree cond,
+ walk_tree_lh lh)
{
hash_set<tree> pset;
struct c_omp_check_loop_iv_data data;
+ int kind = (code != OACC_LOOP && i > 0) ? 4 : 0;
data.declv = declv;
data.fail = false;
@@ -1674,7 +1702,7 @@ c_omp_check_loop_iv_exprs (location_t st
if (init)
{
data.expr_loc = EXPR_LOCATION (init);
- data.kind = 0;
+ data.kind = kind;
walk_tree_1 (&init,
c_omp_check_loop_iv_r, &data, NULL, lh);
}
@@ -1682,7 +1710,7 @@ c_omp_check_loop_iv_exprs (location_t st
{
gcc_assert (COMPARISON_CLASS_P (cond));
data.expr_loc = EXPR_LOCATION (init);
- data.kind = 1;
+ data.kind = kind | 1;
if (TREE_OPERAND (cond, 0) == decl)
walk_tree_1 (&TREE_OPERAND (cond, 1),
c_omp_check_loop_iv_r, &data, NULL, lh);
@@ -9211,7 +9211,7 @@ handle_omp_for_class_iterator (int i, lo
TREE_OPERAND (cond, 1), iter);
return true;
}
- if (!c_omp_check_loop_iv_exprs (locus, orig_declv, i,
+ if (!c_omp_check_loop_iv_exprs (locus, code, orig_declv, i,
TREE_VEC_ELT (declv, i), NULL_TREE,
cond, cp_walk_subtrees))
return true;
@@ -9597,7 +9597,7 @@ finish_omp_for (location_t locus, enum t
tree orig_init;
FOR_EACH_VEC_ELT (*orig_inits, i, orig_init)
if (orig_init
- && !c_omp_check_loop_iv_exprs (locus,
+ && !c_omp_check_loop_iv_exprs (locus, code,
orig_declv ? orig_declv : declv, i,
TREE_VEC_ELT (declv, i), orig_init,
NULL_TREE, cp_walk_subtrees))
@@ -116,7 +116,7 @@ f1 (I<int> &x, I<int> &y, I<int> &u, I<i
for (j = x; j < y; j++)
;
#pragma omp for collapse(2)
- for (i = x; i < y; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */
+ for (i = x; i < y; i = i + 2)
for (j = i; j < v; j += 2)
;
#pragma omp for collapse(2)
@@ -128,11 +128,11 @@ f1 (I<int> &x, I<int> &y, I<int> &u, I<i
for (j = baz (&i); j < v; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */
;
#pragma omp for collapse(2)
- for (i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */
+ for (i = x; i < y; i++)
for (j = v; j > i; j--)
;
#pragma omp for collapse(2)
- for (i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */
+ for (i = x; i < y; i++)
for (j = x; j < i; j++)
;
#pragma omp for collapse(2)
@@ -234,7 +234,7 @@ f2 (I<int> &x, I<int> &y, I<int> &u, I<i
for (I<int> j = u; j < y; j += 2)
;
#pragma omp for collapse(2)
- for (I<int> i = x; i < y; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */
+ for (I<int> i = x; i < y; i = i + 2)
for (I<int> j = i; j < v; j += 2)
;
#pragma omp for collapse(2)
@@ -246,11 +246,11 @@ f2 (I<int> &x, I<int> &y, I<int> &u, I<i
for (I<int> j = baz (&i); j < v; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */
;
#pragma omp for collapse(2)
- for (I<int> i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */
+ for (I<int> i = x; i < y; i++)
for (I<int> j = v; j > i; j--)
;
#pragma omp for collapse(2)
- for (I<int> i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */
+ for (I<int> i = x; i < y; i++)
for (I<int> j = x; j < i; j++)
;
#pragma omp for collapse(2)
@@ -0,0 +1,22 @@
+// PR c++/102854
+// { dg-do compile }
+
+template <typename T>
+void
+foo (T N, T M)
+{
+ #pragma omp parallel for collapse(2)
+ for (T i = 0; i < N; ++i)
+ for (T k = i; k < M; ++k)
+ ;
+ #pragma omp parallel for collapse(2)
+ for (T i = 0; i < N; ++i)
+ for (T k = i; k < 2 * i; ++k)
+ ;
+}
+
+void
+bar ()
+{
+ foo (5, 10);
+}