diff options
Diffstat (limited to 'gcc/fortran/frontend-passes.c')
-rw-r--r-- | gcc/fortran/frontend-passes.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c index 1394fbcdf58..2c1aafebb5f 100644 --- a/gcc/fortran/frontend-passes.c +++ b/gcc/fortran/frontend-passes.c @@ -2461,7 +2461,12 @@ insert_index (gfc_expr *e, gfc_symbol *sym, mpz_t val, mpz_t ret) data.sym = sym; mpz_init_set (data.val, val); gfc_expr_walker (&n, callback_insert_index, (void *) &data); + + /* Suppress errors here - we could get errors here such as an + out of bounds access for arrays, see PR 90563. */ + gfc_push_suppress_errors (); gfc_simplify_expr (n, 0); + gfc_pop_suppress_errors (); if (n->expr_type == EXPR_CONSTANT) { @@ -2511,6 +2516,7 @@ do_subscript (gfc_expr **e) bool have_do_start, have_do_end; bool error_not_proven; int warn; + int sgn; dl = lp->c; if (dl == NULL) @@ -2539,7 +2545,16 @@ do_subscript (gfc_expr **e) Do not warn in this case. */ if (dl->ext.iterator->step->expr_type == EXPR_CONSTANT) - mpz_init_set (do_step, dl->ext.iterator->step->value.integer); + { + sgn = mpz_cmp_ui (dl->ext.iterator->step->value.integer, 0); + /* This can happen, but then the error has been + reported previusly. */ + if (sgn == 0) + continue; + + mpz_init_set (do_step, dl->ext.iterator->step->value.integer); + } + else continue; @@ -2563,6 +2578,16 @@ do_subscript (gfc_expr **e) if (!have_do_start && !have_do_end) return 0; + /* No warning inside a zero-trip loop. */ + if (have_do_start && have_do_end) + { + int cmp; + + cmp = mpz_cmp (do_end, do_start); + if ((sgn > 0 && cmp < 0) || (sgn < 0 && cmp > 0)) + break; + } + /* May have to correct the end value if the step does not equal one. */ if (have_do_start && have_do_end && mpz_cmp_ui (do_step, 1) != 0) |