diff options
author | Martin Liska <mliska@suse.cz> | 2016-07-07 15:15:39 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2016-07-07 13:15:39 +0000 |
commit | 1c122092dcf48801c638abdf070f18c6fe025ad6 (patch) | |
tree | 22f4b1f8abca321823c347e6673350df6ccef09d /gcc/fortran/resolve.c | |
parent | 9cc6b3f86acd4911d6cbd6f57cb3148c52e89d38 (diff) | |
download | gcc-1c122092dcf48801c638abdf070f18c6fe025ad6.zip gcc-1c122092dcf48801c638abdf070f18c6fe025ad6.tar.gz gcc-1c122092dcf48801c638abdf070f18c6fe025ad6.tar.bz2 |
Optimize fortran loops with +-1 step.
* gfortran.dg/do_1.f90: Remove a corner case that triggers
an undefined behavior.
* gfortran.dg/do_3.F90: Likewise.
* gfortran.dg/do_check_11.f90: New test.
* gfortran.dg/do_check_12.f90: New test.
* gfortran.dg/do_corner_warn.f90: New test.
* lang.opt (Wundefined-do-loop): New option.
* resolve.c (gfc_resolve_iterator): Warn for Wundefined-do-loop.
(gfc_trans_simple_do): Generate a c-style loop.
(gfc_trans_do): Fix GNU coding style.
* invoke.texi: Mention the new warning.
From-SVN: r238114
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r-- | gcc/fortran/resolve.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index 4378313..1fc540a 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -6546,6 +6546,29 @@ gfc_resolve_iterator (gfc_iterator *iter, bool real_ok, bool own_scope) &iter->step->where); } + if (iter->end->expr_type == EXPR_CONSTANT + && iter->end->ts.type == BT_INTEGER + && iter->step->expr_type == EXPR_CONSTANT + && iter->step->ts.type == BT_INTEGER + && (mpz_cmp_si (iter->step->value.integer, -1L) == 0 + || mpz_cmp_si (iter->step->value.integer, 1L) == 0)) + { + bool is_step_positive = mpz_cmp_ui (iter->step->value.integer, 1) == 0; + int k = gfc_validate_kind (BT_INTEGER, iter->end->ts.kind, false); + + if (is_step_positive + && mpz_cmp (iter->end->value.integer, gfc_integer_kinds[k].huge) == 0) + gfc_warning (OPT_Wundefined_do_loop, + "DO loop at %L is undefined as it overflows", + &iter->step->where); + else if (!is_step_positive + && mpz_cmp (iter->end->value.integer, + gfc_integer_kinds[k].min_int) == 0) + gfc_warning (OPT_Wundefined_do_loop, + "DO loop at %L is undefined as it underflows", + &iter->step->where); + } + return true; } |