aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/resolve.c
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2016-07-07 15:15:39 +0200
committerMartin Liska <marxin@gcc.gnu.org>2016-07-07 13:15:39 +0000
commit1c122092dcf48801c638abdf070f18c6fe025ad6 (patch)
tree22f4b1f8abca321823c347e6673350df6ccef09d /gcc/fortran/resolve.c
parent9cc6b3f86acd4911d6cbd6f57cb3148c52e89d38 (diff)
downloadgcc-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.c23
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;
}