Hi! In 4.0 and earlier, there has just been a restriction that the lb, b and incr expressions in the syntax (low/high bounds and step) can't change their values during the loop, but in OpenMP 4.5 we have even stronger restriction, the iterators may not be referenced in there at all, so even if you ignore the value, or multiply or and with 0, subtract it from itself etc., it is still invalid. That means the compiler can actually easily diagnose invalid loops.
2015-10-19 Jakub Jelinek <ja...@redhat.com> gcc/ * tree.h (OMP_FOR_ORIG_DECLS): Use OMP_LOOP_CHECK instead of OMP_FOR_CHECK. Remove comment. * tree.def (OMP_SIMD, CILK_SIMD, CILK_FOR, OMP_DISTRIBUTE, OMP_TASKLOOP, OACC_LOOP): Add OMP_FOR_ORIG_DECLS argument. gcc/c-family/ * c-common.h (c_omp_check_loop_iv, c_omp_check_loop_iv_exprs): New prototypes. * c-omp.c (c_finish_omp_for): Store OMP_FOR_ORIG_DECLS always. Don't call add_stmt here. (struct c_omp_check_loop_iv_data): New type. (c_omp_check_loop_iv_r, c_omp_check_loop_iv, c_omp_check_loop_iv_exprs): New functions. gcc/c/ * c-parser.c (c_parser_omp_for_loop): Call c_omp_check_loop_iv. Call add_stmt here. gcc/cp/ * cp-tree.h (finish_omp_for): Add ORIG_INITS argument. * parser.c (cp_parser_omp_for_loop_init): Add ORIG_INIT argument, initialize it. (cp_parser_omp_for_loop): Compute orig_inits, pass it's address to finish_omp_for. * pt.c (tsubst_expr): Use OMP_FOR_ORIG_DECLS for all OpenMP/OpenACC/Cilk+ looping constructs. Adjust finish_omp_for caller. * semantics.c (handle_omp_for_class_iterator): Add ORIG_DECLS argument. Call c_omp_check_loop_iv_exprs on cond. (finish_omp_for): Add ORIG_INITS argument. Call c_omp_check_loop_iv_exprs on ORIG_INITS elements. Adjust handle_omp_for_class_iterator caller. Call c_omp_check_loop_iv. Call add_stmt. gcc/testsuite/ * c-c++-common/gomp/pr67521.c: Add dg-error directives. * gcc.dg/gomp/loop-1.c: New test. * g++.dg/gomp/pr38639.C (foo): Adjust dg-error. (bar): Remove dg-message. * g++.dg/gomp/loop-1.C: New test. * g++.dg/gomp/loop-2.C: New test. * g++.dg/gomp/loop-3.C: New test. --- gcc/tree.h.jj 2015-10-14 10:24:55.000000000 +0200 +++ gcc/tree.h 2015-10-19 12:01:11.390680056 +0200 @@ -1264,8 +1264,7 @@ extern void protected_set_expr_location #define OMP_FOR_COND(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 3) #define OMP_FOR_INCR(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 4) #define OMP_FOR_PRE_BODY(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 5) -/* Note that this is only available for OMP_FOR, hence OMP_FOR_CHECK. */ -#define OMP_FOR_ORIG_DECLS(NODE) TREE_OPERAND (OMP_FOR_CHECK (NODE), 6) +#define OMP_FOR_ORIG_DECLS(NODE) TREE_OPERAND (OMP_LOOP_CHECK (NODE), 6) #define OMP_SECTIONS_BODY(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 0) #define OMP_SECTIONS_CLAUSES(NODE) TREE_OPERAND (OMP_SECTIONS_CHECK (NODE), 1) --- gcc/tree.def.jj 2015-10-14 10:25:43.000000000 +0200 +++ gcc/tree.def 2015-10-19 12:00:50.282982246 +0200 @@ -1101,28 +1101,28 @@ DEFTREECODE (OMP_TASK, "omp_task", tcc_s DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 7) /* OpenMP - #pragma omp simd [clause1 ... clauseN] - Operands like operands 1-6 of OMP_FOR. */ -DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 6) + Operands like for OMP_FOR. */ +DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 7) /* Cilk Plus - #pragma simd [clause1 ... clauseN] - Operands like operands 1-6 of OMP_FOR. */ -DEFTREECODE (CILK_SIMD, "cilk_simd", tcc_statement, 6) + Operands like for OMP_FOR. */ +DEFTREECODE (CILK_SIMD, "cilk_simd", tcc_statement, 7) /* Cilk Plus - _Cilk_for (..) - Operands like operands 1-6 of OMP_FOR. */ -DEFTREECODE (CILK_FOR, "cilk_for", tcc_statement, 6) + Operands like for OMP_FOR. */ +DEFTREECODE (CILK_FOR, "cilk_for", tcc_statement, 7) /* OpenMP - #pragma omp distribute [clause1 ... clauseN] - Operands like operands 1-6 of OMP_FOR. */ -DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 6) + Operands like for OMP_FOR. */ +DEFTREECODE (OMP_DISTRIBUTE, "omp_distribute", tcc_statement, 7) /* OpenMP - #pragma omp taskloop [clause1 ... clauseN] - Operands like operands 1-6 of OMP_FOR. */ -DEFTREECODE (OMP_TASKLOOP, "omp_taskloop", tcc_statement, 6) + Operands like for OMP_FOR. */ +DEFTREECODE (OMP_TASKLOOP, "omp_taskloop", tcc_statement, 7) /* OpenMP - #pragma acc loop [clause1 ... clauseN] - Operands like operands 1-6 of OMP_FOR. */ -DEFTREECODE (OACC_LOOP, "oacc_loop", tcc_statement, 6) + Operands like for OMP_FOR. */ +DEFTREECODE (OACC_LOOP, "oacc_loop", tcc_statement, 7) /* OpenMP - #pragma omp teams [clause1 ... clauseN] Operand 0: OMP_TEAMS_BODY: Teams body. --- gcc/c-family/c-common.h.jj 2015-10-14 10:24:54.000000000 +0200 +++ gcc/c-family/c-common.h 2015-10-19 15:04:58.740284268 +0200 @@ -1268,6 +1268,9 @@ extern void c_finish_omp_taskwait (locat extern void c_finish_omp_taskyield (location_t); extern tree c_finish_omp_for (location_t, enum tree_code, tree, tree, tree, tree, tree, tree, tree); +extern bool c_omp_check_loop_iv (tree, tree, walk_tree_lh); +extern bool c_omp_check_loop_iv_exprs (location_t, tree, tree, tree, tree, + walk_tree_lh); extern tree c_finish_oacc_wait (location_t, tree, tree); extern void c_omp_split_clauses (location_t, enum tree_code, omp_clause_mask, tree, tree *); --- gcc/c-family/c-omp.c.jj 2015-10-14 10:24:54.000000000 +0200 +++ gcc/c-family/c-omp.c 2015-10-19 17:12:42.211884644 +0200 @@ -683,14 +683,173 @@ c_finish_omp_for (location_t locus, enum OMP_FOR_INCR (t) = incrv; OMP_FOR_BODY (t) = body; OMP_FOR_PRE_BODY (t) = pre_body; - if (code == OMP_FOR) - OMP_FOR_ORIG_DECLS (t) = orig_declv; + OMP_FOR_ORIG_DECLS (t) = orig_declv; SET_EXPR_LOCATION (t, locus); - return add_stmt (t); + return t; } } +/* Type for passing data in between c_omp_check_loop_iv and + c_omp_check_loop_iv_r. */ + +struct c_omp_check_loop_iv_data +{ + tree declv; + bool fail; + location_t stmt_loc; + location_t expr_loc; + int kind; + walk_tree_lh lh; + hash_set<tree> *ppset; +}; + +/* Helper function called via walk_tree, to diagnose uses + of associated loop IVs inside of lb, b and incr expressions + of OpenMP loops. */ + +static tree +c_omp_check_loop_iv_r (tree *tp, int *walk_subtrees, void *data) +{ + struct c_omp_check_loop_iv_data *d + = (struct c_omp_check_loop_iv_data *) data; + if (DECL_P (*tp)) + { + int i; + for (i = 0; i < TREE_VEC_LENGTH (d->declv); i++) + if (*tp == TREE_VEC_ELT (d->declv, i)) + { + location_t loc = d->expr_loc; + if (loc == UNKNOWN_LOCATION) + loc = d->stmt_loc; + switch (d->kind) + { + case 0: + error_at (loc, "initializer expression refers to " + "iteration variable %qD", *tp); + break; + case 1: + error_at (loc, "condition expression refers to " + "iteration variable %qD", *tp); + break; + case 2: + error_at (loc, "increment expression refers to " + "iteration variable %qD", *tp); + break; + } + d->fail = true; + } + } + /* Don't walk dtors added by C++ wrap_cleanups_r. */ + else if (TREE_CODE (*tp) == TRY_CATCH_EXPR + && TRY_CATCH_IS_CLEANUP (*tp)) + { + *walk_subtrees = 0; + return walk_tree_1 (&TREE_OPERAND (*tp, 0), c_omp_check_loop_iv_r, data, + d->ppset, d->lh); + } + + return NULL_TREE; +} + +/* Diagnose invalid references to loop iterators in lb, b and incr + expressions. */ + +bool +c_omp_check_loop_iv (tree stmt, tree declv, walk_tree_lh lh) +{ + hash_set<tree> pset; + struct c_omp_check_loop_iv_data data; + int i; + + data.declv = declv; + data.fail = false; + data.stmt_loc = EXPR_LOCATION (stmt); + data.lh = lh; + data.ppset = &pset; + for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++) + { + tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i); + gcc_assert (TREE_CODE (init) == MODIFY_EXPR); + tree decl = TREE_OPERAND (init, 0); + tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i); + gcc_assert (COMPARISON_CLASS_P (cond)); + gcc_assert (TREE_OPERAND (cond, 0) == decl); + tree incr = TREE_VEC_ELT (OMP_FOR_INCR (stmt), i); + data.expr_loc = EXPR_LOCATION (TREE_OPERAND (init, 1)); + data.kind = 0; + walk_tree_1 (&TREE_OPERAND (init, 1), + c_omp_check_loop_iv_r, &data, &pset, lh); + /* Don't warn for C++ random access iterators here, the + expression then involves the subtraction and always refers + to the original value. The C++ FE needs to warn on those + earlier. */ + if (decl == TREE_VEC_ELT (declv, i)) + { + data.expr_loc = EXPR_LOCATION (cond); + data.kind = 1; + walk_tree_1 (&TREE_OPERAND (cond, 1), + c_omp_check_loop_iv_r, &data, &pset, lh); + } + if (TREE_CODE (incr) == MODIFY_EXPR) + { + gcc_assert (TREE_OPERAND (incr, 0) == decl); + incr = TREE_OPERAND (incr, 1); + data.kind = 2; + if (TREE_CODE (incr) == PLUS_EXPR + && TREE_OPERAND (incr, 1) == decl) + { + data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 0)); + walk_tree_1 (&TREE_OPERAND (incr, 0), + c_omp_check_loop_iv_r, &data, &pset, lh); + } + else + { + data.expr_loc = EXPR_LOCATION (TREE_OPERAND (incr, 1)); + walk_tree_1 (&TREE_OPERAND (incr, 1), + c_omp_check_loop_iv_r, &data, &pset, lh); + } + } + } + return !data.fail; +} + +/* Similar, but allows to check the init or cond expressions individually. */ + +bool +c_omp_check_loop_iv_exprs (location_t stmt_loc, tree declv, tree decl, + tree init, tree cond, walk_tree_lh lh) +{ + hash_set<tree> pset; + struct c_omp_check_loop_iv_data data; + + data.declv = declv; + data.fail = false; + data.stmt_loc = stmt_loc; + data.lh = lh; + data.ppset = &pset; + if (init) + { + data.expr_loc = EXPR_LOCATION (init); + data.kind = 0; + walk_tree_1 (&init, + c_omp_check_loop_iv_r, &data, &pset, lh); + } + if (cond) + { + gcc_assert (COMPARISON_CLASS_P (cond)); + data.expr_loc = EXPR_LOCATION (init); + data.kind = 1; + if (TREE_OPERAND (cond, 0) == decl) + walk_tree_1 (&TREE_OPERAND (cond, 1), + c_omp_check_loop_iv_r, &data, &pset, lh); + else + walk_tree_1 (&TREE_OPERAND (cond, 0), + c_omp_check_loop_iv_r, &data, &pset, lh); + } + return !data.fail; +} + /* Right now we have 21 different combined/composite constructs, this function attempts to split or duplicate clauses for combined constructs. CODE is the innermost construct in the combined construct, --- gcc/c/c-parser.c.jj 2015-10-19 12:39:22.000000000 +0200 +++ gcc/c/c-parser.c 2015-10-19 15:18:40.928501691 +0200 @@ -13991,8 +13991,15 @@ c_parser_omp_for_loop (location_t loc, c { stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv, incrv, body, pre_body); + + /* Check for iterators appearing in lb, b or incr expressions. */ + if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL)) + stmt = NULL_TREE; + if (stmt) { + add_stmt (stmt); + if (cclauses != NULL && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL) { --- gcc/cp/cp-tree.h.jj 2015-10-14 10:25:31.000000000 +0200 +++ gcc/cp/cp-tree.h 2015-10-19 14:43:41.571508885 +0200 @@ -6326,7 +6326,7 @@ extern tree begin_omp_task (void); extern tree finish_omp_task (tree, tree); extern tree finish_omp_for (location_t, enum tree_code, tree, tree, tree, tree, tree, - tree, tree, tree); + tree, tree, vec<tree> *, tree); extern void finish_omp_atomic (enum tree_code, enum tree_code, tree, tree, tree, tree, tree, bool); --- gcc/cp/parser.c.jj 2015-10-15 17:36:30.000000000 +0200 +++ gcc/cp/parser.c 2015-10-19 14:43:21.592793906 +0200 @@ -32447,6 +32447,7 @@ cp_parser_omp_for_loop_init (cp_parser * tree &this_pre_body, vec<tree, va_gc> *for_block, tree &init, + tree &orig_init, tree &decl, tree &real_decl) { @@ -32544,6 +32545,7 @@ cp_parser_omp_for_loop_init (cp_parser * cp_finish_decl (decl, init, !is_non_constant_init, asm_specification, LOOKUP_ONLYCONVERTING); + orig_init = init; if (CLASS_TYPE_P (TREE_TYPE (decl))) { vec_safe_push (for_block, this_pre_body); @@ -32621,6 +32623,7 @@ cp_parser_omp_for_loop_init (cp_parser * cp_parser_parse_definitely (parser); cp_parser_require (parser, CPP_EQ, RT_EQ); rhs = cp_parser_assignment_expression (parser); + orig_init = rhs; finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs), decl, NOP_EXPR, rhs, @@ -32650,13 +32653,14 @@ static tree cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses, tree *cclauses) { - tree init, cond, incr, body, decl, pre_body = NULL_TREE, ret; + tree init, orig_init, cond, incr, body, decl, pre_body = NULL_TREE, ret; tree real_decl, initv, condv, incrv, declv; tree this_pre_body, cl, ordered_cl = NULL_TREE; location_t loc_first; bool collapse_err = false; int i, collapse = 1, ordered = 0, count, nbraces = 0; vec<tree, va_gc> *for_block = make_tree_vector (); + auto_vec<tree, 4> orig_inits; for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) @@ -32723,13 +32727,13 @@ cp_parser_omp_for_loop (cp_parser *parse if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN)) return NULL; - init = decl = real_decl = NULL; + init = orig_init = decl = real_decl = NULL; this_pre_body = push_stmt_list (); add_private_clause = cp_parser_omp_for_loop_init (parser, code, this_pre_body, for_block, - init, decl, real_decl); + init, orig_init, decl, real_decl); cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); if (this_pre_body) @@ -32861,6 +32865,11 @@ cp_parser_omp_for_loop (cp_parser *parse TREE_VEC_ELT (initv, i) = init; TREE_VEC_ELT (condv, i) = cond; TREE_VEC_ELT (incrv, i) = incr; + if (orig_init) + { + orig_inits.safe_grow_cleared (i + 1); + orig_inits[i] = orig_init; + } if (i == count - 1) break; @@ -32918,7 +32927,7 @@ cp_parser_omp_for_loop (cp_parser *parse ret = NULL_TREE; else ret = finish_omp_for (loc_first, code, declv, NULL, initv, condv, incrv, - body, pre_body, clauses); + body, pre_body, &orig_inits, clauses); while (nbraces) { --- gcc/cp/pt.c.jj 2015-10-14 10:25:31.000000000 +0200 +++ gcc/cp/pt.c 2015-10-19 14:44:36.485725467 +0200 @@ -15237,7 +15237,7 @@ tsubst_expr (tree t, tree args, tsubst_f if (OMP_FOR_INIT (t) != NULL_TREE) { declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t))); - if (TREE_CODE (t) == OMP_FOR && OMP_FOR_ORIG_DECLS (t)) + if (OMP_FOR_ORIG_DECLS (t)) orig_declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t))); initv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t))); condv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t))); @@ -15264,7 +15264,7 @@ tsubst_expr (tree t, tree args, tsubst_f if (OMP_FOR_INIT (t) != NULL_TREE) t = finish_omp_for (EXPR_LOCATION (t), TREE_CODE (t), declv, orig_declv, initv, condv, incrv, body, pre_body, - clauses); + NULL, clauses); else { t = make_node (TREE_CODE (t)); --- gcc/cp/semantics.c.jj 2015-10-16 17:08:35.000000000 +0200 +++ gcc/cp/semantics.c 2015-10-19 15:58:13.386683491 +0200 @@ -7286,9 +7286,10 @@ finish_omp_task (tree clauses, tree body static bool handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code, - tree declv, tree initv, tree condv, tree incrv, - tree *body, tree *pre_body, tree &clauses, - tree *lastp, int collapse, int ordered) + tree declv, tree orig_declv, tree initv, + tree condv, tree incrv, tree *body, + tree *pre_body, tree &clauses, tree *lastp, + int collapse, int ordered) { tree diff, iter_init, iter_incr = NULL, last; tree incr_var = NULL, orig_pre_body, orig_body, c; @@ -7345,6 +7346,10 @@ 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, + TREE_VEC_ELT (declv, i), NULL_TREE, + cond, cp_walk_subtrees)) + return true; switch (TREE_CODE (incr)) { @@ -7600,7 +7605,7 @@ handle_omp_for_class_iterator (int i, lo tree finish_omp_for (location_t locus, enum tree_code code, tree declv, tree orig_declv, tree initv, tree condv, tree incrv, - tree body, tree pre_body, tree clauses) + tree body, tree pre_body, vec<tree> *orig_inits, tree clauses) { tree omp_for = NULL, orig_incr = NULL; tree decl = NULL, init, cond, incr, orig_decl = NULL_TREE, block = NULL_TREE; @@ -7676,6 +7681,20 @@ finish_omp_for (location_t locus, enum t TREE_VEC_ELT (initv, i) = init; } + if (orig_inits) + { + bool fail = false; + tree orig_init; + FOR_EACH_VEC_ELT (*orig_inits, i, orig_init) + if (orig_init + && !c_omp_check_loop_iv_exprs (locus, declv, + TREE_VEC_ELT (declv, i), orig_init, + NULL_TREE, cp_walk_subtrees)) + fail = true; + if (fail) + return NULL; + } + if (dependent_omp_for_p (declv, initv, condv, incrv)) { tree stmt; @@ -7749,10 +7768,10 @@ finish_omp_for (location_t locus, enum t } if (code == CILK_FOR && i == 0) orig_decl = decl; - if (handle_omp_for_class_iterator (i, locus, code, declv, initv, - condv, incrv, &body, &pre_body, - clauses, &last, collapse, - ordered)) + if (handle_omp_for_class_iterator (i, locus, code, declv, orig_declv, + initv, condv, incrv, &body, + &pre_body, clauses, &last, + collapse, ordered)) return NULL; continue; } @@ -7811,6 +7830,10 @@ finish_omp_for (location_t locus, enum t omp_for = c_finish_omp_for (locus, code, declv, orig_declv, initv, condv, incrv, body, pre_body); + /* Check for iterators appearing in lb, b or incr expressions. */ + if (omp_for && !c_omp_check_loop_iv (omp_for, orig_declv, cp_walk_subtrees)) + omp_for = NULL_TREE; + if (omp_for == NULL) { if (block) @@ -7818,6 +7841,8 @@ finish_omp_for (location_t locus, enum t return NULL; } + add_stmt (omp_for); + for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INCR (omp_for)); i++) { decl = TREE_OPERAND (TREE_VEC_ELT (OMP_FOR_INIT (omp_for), i), 0); --- gcc/testsuite/c-c++-common/gomp/pr67521.c.jj 2015-10-19 11:07:17.631880902 +0200 +++ gcc/testsuite/c-c++-common/gomp/pr67521.c 2015-10-19 11:07:55.249342590 +0200 @@ -7,14 +7,14 @@ foo (int x) { int i = 0; #pragma omp parallel for simd - for (i = (i & x); i < 10; i = i + 2) + for (i = (i & x); i < 10; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */ ; i = 0; #pragma omp parallel for simd - for (i = 0; i < (i & x) + 10; i = i + 2) + for (i = 0; i < (i & x) + 10; i = i + 2) /* { dg-error "condition expression refers to iteration variable" } */ ; i = 0; #pragma omp parallel for simd - for (i = 0; i < 10; i = i + ((i & x) + 2)) + for (i = 0; i < 10; i = i + ((i & x) + 2)) /* { dg-error "increment expression refers to iteration variable" } */ ; } --- gcc/testsuite/gcc.dg/gomp/loop-1.c.jj 2015-10-19 10:20:03.442502890 +0200 +++ gcc/testsuite/gcc.dg/gomp/loop-1.c 2015-10-19 11:56:25.848768035 +0200 @@ -0,0 +1,283 @@ +int bar (int); +int baz (int *); + +void +f1 (int x) +{ + int i = 0, j = 0; + #pragma omp for + for (i = 0; i < 16; i++) + ; + #pragma omp for + for (i = 0; 16 > i; i++) + ; + #pragma omp for + for (i = 0; i < 16; i = i + 2) + ; + #pragma omp for + for (i = 0; i < 16; i = 2 + i) + ; + #pragma omp for /* { dg-error "initializer expression refers to iteration variable" } */ + for (i = i; i < 16; i++) + ; + #pragma omp for + for (i = 2 * (i & x); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = bar (i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = baz (&i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 2 * i + 17; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; 2 * i + 17 > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; bar (i) > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i <= baz (&i); i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i <= i; i++) /* { dg-error "invalid controlling predicate|condition expression refers to iteration variable" } */ + ; + #pragma omp for /* { dg-error "increment expression refers to iteration variable" } */ + for (i = 5; i < 16; i += i) + ; + #pragma omp for + for (i = 5; i < 16; i = i + 2 * i) /* { dg-error "invalid increment expression|increment expression refers to iteration variable" } */ + ; + #pragma omp for /* { dg-error "increment expression refers to iteration variable" } */ + for (i = 5; i < 16; i = i + i) + ; + #pragma omp for + for (i = 5; i < 16; i = i + bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = baz (&i) + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i += bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i += baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = i + 2) + for (j = 0; j < 16; j += 2) + ; + #pragma omp for collapse(2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (i = j; i < 16; i = i + 2) + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (i = 0; i < 16; i = i + 2) + for (j = i; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = i + 2) + for (j = i + 3; j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = baz (&i); j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = 16; j > (i & x); j--) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = 0; j < i; j++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = 0; j < i + 4; j++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < j + 4; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < j; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < bar (j); i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = 0; j < baz (&i); j++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) /* { dg-error "increment expression refers to iteration variable" } */ + for (i = 0; i < 16; i += j) + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) /* { dg-error "increment expression refers to iteration variable" } */ + for (i = 0; i < 16; i++) + for (j = 0; j < 16; j += i) + ; + #pragma omp for collapse(2) /* { dg-error "increment expression refers to iteration variable" } */ + for (i = 0; i < 16; i = j + i) + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) /* { dg-error "increment expression refers to iteration variable" } */ + for (i = 0; i < 16; i++) + for (j = 0; j < 16; j = j + i) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = bar (j) + i) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = 0; j < 16; j = j + baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; +} + +void +f2 (int x) +{ + #pragma omp for + for (int i = 0; i < 16; i++) + ; + #pragma omp for + for (int i = 0; 16 > i; i++) + ; + #pragma omp for + for (int i = 0; i < 16; i = i + 2) + ; + #pragma omp for + for (int i = 0; i < 16; i = 2 + i) + ; + #pragma omp for /* { dg-error "initializer expression refers to iteration variable" } */ + for (int i = i; i < 16; i++) + ; + #pragma omp for + for (int i = 2 * (i & x); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = bar (i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = baz (&i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 2 * i + 17; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; 2 * i + 17 > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; bar (i) > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i <= baz (&i); i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i <= i; i++) /* { dg-error "invalid controlling predicate|condition expression refers to iteration variable" } */ + ; + #pragma omp for /* { dg-error "increment expression refers to iteration variable" } */ + for (int i = 5; i < 16; i += i) + ; + #pragma omp for + for (int i = 5; i < 16; i = i + 2 * i) /* { dg-error "invalid increment expression|increment expression refers to iteration variable" } */ + ; + #pragma omp for /* { dg-error "increment expression refers to iteration variable" } */ + for (int i = 5; i < 16; i = i + i) + ; + #pragma omp for + for (int i = 5; i < 16; i = i + bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = baz (&i) + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i += bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i += baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = i + 2) + for (int j = 0; j < 16; j += 2) + ; + #pragma omp for collapse(2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (int i = 0; i < 16; i = i + 2) + for (int j = i; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = i + 2) + for (int j = i + 3; j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = baz (&i); j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = 16; j > (i & x); j--) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = 0; j < i; j++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = 0; j < i + 4; j++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = 0; j < baz (&i); j++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) /* { dg-error "increment expression refers to iteration variable" } */ + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j += i) + ; + #pragma omp for collapse(2) /* { dg-error "increment expression refers to iteration variable" } */ + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j = j + i) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j = j + baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; +} + +void +f3 (void) +{ + int j = 0; + #pragma omp for collapse(2) + for (int i = j; i < 16; i = i + 2) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < j + 4; i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < j; i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < bar (j); i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i += j) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = j + i) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = bar (j) + i) + for (int j = 0; j < 16; j++) + ; +} --- gcc/testsuite/g++.dg/gomp/pr38639.C.jj 2015-10-14 10:25:28.000000000 +0200 +++ gcc/testsuite/g++.dg/gomp/pr38639.C 2015-10-19 15:09:38.005272514 +0200 @@ -6,12 +6,12 @@ template<int> void foo () { #pragma omp parallel for - for (auto i = i = 0; i<4; ++i) // { dg-error "incomplete|unable|invalid|auto" } + for (auto i = i = 0; i<4; ++i) // { dg-error "initializer expression refers to iteration variable" } ; } void bar () { - foo<0> (); // { dg-message "required from here" } + foo<0> (); } --- gcc/testsuite/g++.dg/gomp/loop-1.C.jj 2015-10-19 13:07:38.469657173 +0200 +++ gcc/testsuite/g++.dg/gomp/loop-1.C 2015-10-19 13:18:05.659683587 +0200 @@ -0,0 +1,283 @@ +int bar (int); +int baz (int *); + +void +f1 (int x) +{ + int i = 0, j = 0; + #pragma omp for + for (i = 0; i < 16; i++) + ; + #pragma omp for + for (i = 0; 16 > i; i++) + ; + #pragma omp for + for (i = 0; i < 16; i = i + 2) + ; + #pragma omp for + for (i = 0; i < 16; i = 2 + i) + ; + #pragma omp for + for (i = i; i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 2 * (i & x); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = bar (i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = baz (&i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 2 * i + 17; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; 2 * i + 17 > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; bar (i) > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i <= baz (&i); i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i <= i; i++) /* { dg-error "invalid controlling predicate|condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i += i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = i + 2 * i) /* { dg-error "invalid increment expression|increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = i + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = i + bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = baz (&i) + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i += bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i += baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = i + 2) + for (j = 0; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (i = j; i < 16; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (j = i; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = i + 2) + for (j = i + 3; j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + for (j = baz (&i); j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 16; j > (i & x); j--) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < i; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < i + 4; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < j + 4; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < j; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < bar (j); i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < baz (&i); j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i += j) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j += i) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = j + i) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j = j + i) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = bar (j) + i) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = 0; j < 16; j = j + baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; +} + +void +f2 (int x) +{ + #pragma omp for + for (int i = 0; i < 16; i++) + ; + #pragma omp for + for (int i = 0; 16 > i; i++) + ; + #pragma omp for + for (int i = 0; i < 16; i = i + 2) + ; + #pragma omp for + for (int i = 0; i < 16; i = 2 + i) + ; + #pragma omp for + for (int i = i; i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 2 * (i & x); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = bar (i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = baz (&i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 2 * i + 17; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; 2 * i + 17 > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; bar (i) > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i <= baz (&i); i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i <= i; i++) /* { dg-error "invalid controlling predicate|condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i += i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = i + 2 * i) /* { dg-error "invalid increment expression|increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = i + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = i + bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = baz (&i) + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i += bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i += baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = i + 2) + for (int j = 0; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (int j = i; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = i + 2) + for (int j = i + 3; j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + for (int j = baz (&i); j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (int j = 16; j > (i & x); j--) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (int j = 0; j < i; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (int j = 0; j < i + 4; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (int j = 0; j < baz (&i); j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "increment expression refers to iteration variable" } */ + for (int j = 0; j < 16; j += i) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "increment expression refers to iteration variable" } */ + for (int j = 0; j < 16; j = j + i) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j = j + baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; +} + +void +f3 (void) +{ + int j = 0; + #pragma omp for collapse(2) + for (int i = j; i < 16; i = i + 2) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < j + 4; i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < j; i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < bar (j); i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i += j) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = j + i) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = bar (j) + i) + for (int j = 0; j < 16; j++) + ; +} --- gcc/testsuite/g++.dg/gomp/loop-2.C.jj 2015-10-19 15:10:38.145407819 +0200 +++ gcc/testsuite/g++.dg/gomp/loop-2.C 2015-10-19 15:12:42.936613569 +0200 @@ -0,0 +1,294 @@ +int bar (int); +int baz (int *); + +template <int N> +void +f1 (int x) +{ + int i = 0, j = 0; + #pragma omp for + for (i = 0; i < 16; i++) + ; + #pragma omp for + for (i = 0; 16 > i; i++) + ; + #pragma omp for + for (i = 0; i < 16; i = i + 2) + ; + #pragma omp for + for (i = 0; i < 16; i = 2 + i) + ; + #pragma omp for + for (i = i; i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 2 * (i & x); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = bar (i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = baz (&i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 2 * i + 17; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; 2 * i + 17 > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; bar (i) > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i <= baz (&i); i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i <= i; i++) /* { dg-error "invalid controlling predicate|condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i += i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = i + 2 * i) /* { dg-error "invalid increment expression|increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = i + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = i + bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i = baz (&i) + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i += bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = 5; i < 16; i += baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = i + 2) + for (j = 0; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (i = j; i < 16; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (j = i; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = i + 2) + for (j = i + 3; j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = baz (&i); j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 16; j > (i & x); j--) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < i; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < i + 4; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < j + 4; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < j; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < bar (j); i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = 0; j < baz (&i); j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i += j) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j += i) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = j + i) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j = j + i) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i = bar (j) + i) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (i = 0; i < 16; i++) + for (j = 0; j < 16; j = j + baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; +} + +template <int N> +void +f2 (int x) +{ + #pragma omp for + for (int i = 0; i < 16; i++) + ; + #pragma omp for + for (int i = 0; 16 > i; i++) + ; + #pragma omp for + for (int i = 0; i < 16; i = i + 2) + ; + #pragma omp for + for (int i = 0; i < 16; i = 2 + i) + ; + #pragma omp for + for (int i = i; i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 2 * (i & x); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = bar (i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = baz (&i); i < 16; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 2 * i + 17; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; 2 * i + 17 > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; bar (i) > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i <= baz (&i); i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i <= i; i++) /* { dg-error "invalid controlling predicate|condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i += i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = i + 2 * i) /* { dg-error "invalid increment expression|increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = i + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = i + bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i = baz (&i) + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i += bar (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (int i = 5; i < 16; i += baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = i + 2) + for (int j = 0; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */ + for (int j = i; j < 16; j += 2) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = i + 2) + for (int j = i + 3; j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = baz (&i); j < 16; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (int j = 16; j > (i & x); j--) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (int j = 0; j < i; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (int j = 0; j < i + 4; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (int j = 0; j < baz (&i); j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "increment expression refers to iteration variable" } */ + for (int j = 0; j < 16; j += i) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) /* { dg-error "increment expression refers to iteration variable" } */ + for (int j = 0; j < 16; j = j + i) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i++) + for (int j = 0; j < 16; j = j + baz (&i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; +} + +template <int N> +void +f3 () +{ + int j = 0; + #pragma omp for collapse(2) + for (int i = j; i < 16; i = i + 2) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < j + 4; i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < j; i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < bar (j); i++) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i += j) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = j + i) + for (int j = 0; j < 16; j++) + ; + #pragma omp for collapse(2) + for (int i = 0; i < 16; i = bar (j) + i) + for (int j = 0; j < 16; j++) + ; +} + +void +foo () +{ + f1 <0> (0); + f2 <0> (0); + f3 <0> (); +} --- gcc/testsuite/g++.dg/gomp/loop-3.C.jj 2015-10-19 15:20:12.909189004 +0200 +++ gcc/testsuite/g++.dg/gomp/loop-3.C 2015-10-19 16:19:30.119481730 +0200 @@ -0,0 +1,306 @@ +typedef __PTRDIFF_TYPE__ ptrdiff_t; + +template <typename T> +class I +{ +public: + typedef ptrdiff_t difference_type; + I (); + ~I (); + I (T *); + I (const I &); + T &operator * (); + T *operator -> (); + T &operator [] (const difference_type &) const; + I &operator = (const I &); + I &operator ++ (); + I operator ++ (int); + I &operator -- (); + I operator -- (int); + I &operator += (const difference_type &); + I &operator -= (const difference_type &); + I operator + (const difference_type &) const; + I operator - (const difference_type &) const; + template <typename S> friend bool operator == (I<S> &, I<S> &); + template <typename S> friend bool operator == (const I<S> &, const I<S> &); + template <typename S> friend bool operator < (I<S> &, I<S> &); + template <typename S> friend bool operator < (const I<S> &, const I<S> &); + template <typename S> friend bool operator <= (I<S> &, I<S> &); + template <typename S> friend bool operator <= (const I<S> &, const I<S> &); + template <typename S> friend bool operator > (I<S> &, I<S> &); + template <typename S> friend bool operator > (const I<S> &, const I<S> &); + template <typename S> friend bool operator >= (I<S> &, I<S> &); + template <typename S> friend bool operator >= (const I<S> &, const I<S> &); + template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &); + template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &); + template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &); +private: + T *p; +}; + +template <typename T> bool operator == (I<T> &, I<T> &); +template <typename T> bool operator == (const I<T> &, const I<T> &); +template <typename T> bool operator != (I<T> &, I<T> &); +template <typename T> bool operator != (const I<T> &, const I<T> &); +template <typename T> bool operator < (I<T> &, I<T> &); +template <typename T> bool operator < (const I<T> &, const I<T> &); +template <typename T> bool operator <= (I<T> &, I<T> &); +template <typename T> bool operator <= (const I<T> &, const I<T> &); +template <typename T> bool operator > (I<T> &, I<T> &); +template <typename T> bool operator > (const I<T> &, const I<T> &); +template <typename T> bool operator >= (I<T> &, I<T> &); +template <typename T> bool operator >= (const I<T> &, const I<T> &); +template <typename T> typename I<T>::difference_type operator - (I<T> &, I<T> &); +template <typename T> typename I<T>::difference_type operator - (const I<T> &, const I<T> &); +template <typename T> I<T> operator + (typename I<T>::difference_type, const I<T> &); + +ptrdiff_t foo (I<int> &); +I<int> &bar (I<int> &); +I<int> &baz (I<int> *); + +void +f1 (I<int> &x, I<int> &y, I<int> &u, I<int> &v) +{ + I<int> i, j; + #pragma omp for + for (i = x; i < y; i++) + ; + #pragma omp for + for (i = x; y > i; i++) + ; + #pragma omp for + for (i = x; i < y; i = i + 2) + ; + #pragma omp for + for (i = x; i < y; i = 2 + i) + ; + #pragma omp for + for (i = i; i < y; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = i + 3; i < y; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = bar (i); i < y; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = baz (&i); i < y; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = x; i <= i + 5; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = x; i <= baz (&i); i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = x; baz (&i) > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = x; i <= i; i++) /* { dg-error "invalid controlling predicate|condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = x; i < y; i += foo (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = x; i < y; i = i + foo (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (i = x; i < y; i = foo (i) + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = x; i < y; i = i + 2) + for (j = u; j < y; j += 2) + ; + #pragma omp for collapse(2) + for (i = j; i < y; i = i + 2) /* { dg-error "initializer expression refers to iteration variable" } */ + 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 (j = i; j < v; j += 2) + ; + #pragma omp for collapse(2) + for (i = x; i < y; i = i + 2) + for (j = i + 3; j < v; j += 2) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = x; i < y; 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 (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 (j = x; j < i; j++) + ; + #pragma omp for collapse(2) + for (i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = u; j < i + 4; j++) + ; + #pragma omp for collapse(2) + for (i = x; i < j + 4; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (i = x; i < j; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (i = x; i < bar (j); i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (i = x; i < y; i++) /* { dg-error "condition expression refers to iteration variable" } */ + for (j = u; j < baz (&i); j++) + ; + #pragma omp for collapse(2) + for (i = x; i < y; i += foo (j)) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (i = x; i < y; i++) + for (j = u; j < v; j += foo (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = x; i < y; i = foo (j) + i) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (i = x; i < y; i++) + for (j = u; j < y; j = j + (i - v)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (i = x; i < y; i = foo (j) + i) /* { dg-error "increment expression refers to iteration variable" } */ + for (j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (i = x; i < y; i++) + for (j = u; j < v; j = j + foo (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; +} + +void +f2 (I<int> &x, I<int> &y, I<int> &u, I<int> &v) +{ + #pragma omp for + for (I<int> i = x; i < y; i++) + ; + #pragma omp for + for (I<int> i = x; y > i; i++) + ; + #pragma omp for + for (I<int> i = x; i < y; i = i + 2) + ; + #pragma omp for + for (I<int> i = x; i < y; i = 2 + i) + ; + #pragma omp for + for (I<int> i = i; i < y; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = i + 3; i < y; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = bar (i); i < y; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = baz (&i); i < y; i++) /* { dg-error "initializer expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = x; i <= i + 5; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = x; i <= baz (&i); i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = x; baz (&i) > i; i++) /* { dg-error "condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = x; i <= i; i++) /* { dg-error "invalid controlling predicate|condition expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = x; i < y; i += foo (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = x; i < y; i = i + foo (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for + for (I<int> i = x; i < y; i = foo (i) + i) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < y; i = i + 2) + 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> j = i; j < v; j += 2) + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < y; i = i + 2) + for (I<int> j = i + 3; 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++) + 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> 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> j = x; 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> j = u; j < i + 4; 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> j = u; j < baz (&i); j++) + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < y; i++) + for (I<int> j = u; j < v; j += foo (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < y; i++) + for (I<int> j = u; j < y; j = j + (i - v)) /* { dg-error "increment expression refers to iteration variable" } */ + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < y; i++) + for (I<int> j = u; j < v; j = j + foo (i)) /* { dg-error "increment expression refers to iteration variable" } */ + ; +} + +void +f3 (I<int> &x, I<int> &y, I<int> &u, I<int> &v) +{ + I<int> j; + #pragma omp for collapse(2) + for (I<int> i = j; i < y; i = i + 2) + for (I<int> j = x; j < y; j++) + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < j + 4; i++) + for (I<int> j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < j; i++) + for (I<int> j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < bar (j); i++) + for (I<int> j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < y; i += foo (j)) + for (I<int> j = u; j < v; j++) + ; + #pragma omp for collapse(2) + for (I<int> i = x; i < y; i = foo (j) + i) + for (I<int> j = u; j < v; j++) + ; +} Jakub