From a215f7f07e8d5637c2577f4bb92e03906d1d5dab Mon Sep 17 00:00:00 2001 From: marxin Date: Thu, 30 Jun 2016 16:53:51 +0200 Subject: [PATCH 2/2] Catch infinite loops w/ -fcheck-do and -ffast-do-loop gcc/fortran/ChangeLog: 2016-06-30 Martin Liska * trans-stmt.c (gfc_trans_simple_do_fast): Emit a run-time check. gcc/testsuite/ChangeLog: 2016-06-30 Martin Liska * gfortran.dg/do_check_11.f90: New test. * gfortran.dg/do_check_12.f90: New test. --- gcc/fortran/trans-stmt.c | 13 +++++++++++++ gcc/testsuite/gfortran.dg/do_check_11.f90 | 13 +++++++++++++ gcc/testsuite/gfortran.dg/do_check_12.f90 | 13 +++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 gcc/testsuite/gfortran.dg/do_check_11.f90 create mode 100644 gcc/testsuite/gfortran.dg/do_check_12.f90 diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c index b069af3..3b43458 100644 --- a/gcc/fortran/trans-stmt.c +++ b/gcc/fortran/trans-stmt.c @@ -1903,6 +1903,19 @@ gfc_trans_simple_do_fast (gfc_code * code, stmtblock_t *pblock, tree dovar, cond, tmp, build_empty_stmt (loc)); gfc_add_expr_to_block (&body, tmp); + /* Check whether the induction variable is equal to INT_MAX + (respectively to INT_MIN). */ + if (gfc_option.rtcheck & GFC_RTCHECK_DO) + { + tree boundary = is_step_positive ? TYPE_MAX_VALUE (type) + : TYPE_MIN_VALUE (type); + + tmp = fold_build2_loc (loc, EQ_EXPR, boolean_type_node, + dovar, boundary); + gfc_trans_runtime_check (true, false, tmp, &body, &code->loc, + "Loop iterates infinitely"); + } + /* Main loop body. */ tmp = gfc_trans_code_cond (code->block->next, exit_cond); gfc_add_expr_to_block (&body, tmp); diff --git a/gcc/testsuite/gfortran.dg/do_check_11.f90 b/gcc/testsuite/gfortran.dg/do_check_11.f90 new file mode 100644 index 0000000..b86c384 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/do_check_11.f90 @@ -0,0 +1,13 @@ +! { dg-do run } +! { dg-options "-fcheck=do -ffast-do-loop" } +! { dg-shouldfail "DO check" } +! +! Run-time check for infinite loop with -ffast-do-loop +program test + implicit none + integer(1) :: i + do i = HUGE(i)-10, HUGE(i) + print *, i + end do +end program test +! { dg-output "Fortran runtime error: Loop iterates infinitely" } diff --git a/gcc/testsuite/gfortran.dg/do_check_12.f90 b/gcc/testsuite/gfortran.dg/do_check_12.f90 new file mode 100644 index 0000000..5a68aee --- /dev/null +++ b/gcc/testsuite/gfortran.dg/do_check_12.f90 @@ -0,0 +1,13 @@ +! { dg-do run } +! { dg-options "-fcheck=do -ffast-do-loop" } +! { dg-shouldfail "DO check" } +! +! Run-time check for infinite loop with -ffast-do-loop +program test + implicit none + integer(1) :: i + do i = -HUGE(i)+10, -HUGE(i)-1, -1 + print *, i + end do +end program test +! { dg-output "Fortran runtime error: Loop iterates infinitely" } -- 2.8.4