From a50ba82d5881be3796d3a9054092dfd4a615bcfa Mon Sep 17 00:00:00 2001 From: Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> Date: Tue, 18 Sep 2007 21:25:40 +0000 Subject: [PATCH] re PR fortran/31119 (-fbounds-check: Check for presence of optional arguments before bound checking) PR fortran/31119 * trans-array.c (gfc_conv_ss_startstride): Only perform bounds checking for optional args when they are present. * gfortran.dg/bounds_check_9.f90: New test. * gfortran.dg/bounds_check_fail_2.f90: New test. From-SVN: r128587 --- gcc/fortran/ChangeLog | 6 +++ gcc/fortran/trans-array.c | 18 ++++++++- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gfortran.dg/bounds_check_9.f90 | 36 +++++++++++++++++ .../gfortran.dg/bounds_check_fail_2.f90 | 39 +++++++++++++++++++ 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/bounds_check_9.f90 create mode 100644 gcc/testsuite/gfortran.dg/bounds_check_fail_2.f90 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index ad04007c119f..c79242d9dd5c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2007-09-18 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + PR fortran/31119 + * trans-array.c (gfc_conv_ss_startstride): Only perform bounds + checking for optional args when they are present. + 2007-09-18 Tobias Burnus <burnus@net-b.de> PR fortran/33231 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 1e02b81167fa..64a62dbd018d 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -2993,8 +2993,22 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) others against this. */ if (size[n]) { - tree tmp3 - = fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]); + tree tmp3; + + tmp3 = fold_build2 (NE_EXPR, boolean_type_node, tmp, size[n]); + + /* For optional arguments, only check bounds if the + argument is present. */ + if (ss->expr->symtree->n.sym->attr.optional + || ss->expr->symtree->n.sym->attr.not_always_present) + { + tree cond; + + cond = gfc_conv_expr_present (ss->expr->symtree->n.sym); + tmp3 = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, + cond, tmp3); + } + asprintf (&msg, "%s, size mismatch for dimension %d " "of array '%s' (%%ld/%%ld)", gfc_msg_bounds, info->dim[n]+1, ss->expr->symtree->name); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5043613375e4..b0e1b9fa6cd1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-09-18 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + PR fortran/31119 + * gfortran.dg/bounds_check_9.f90: New test. + * gfortran.dg/bounds_check_fail_2.f90: New test. + 2007-09-18 Paolo Carlini <pcarlini@suse.de> PR c++/33462 (again) diff --git a/gcc/testsuite/gfortran.dg/bounds_check_9.f90 b/gcc/testsuite/gfortran.dg/bounds_check_9.f90 new file mode 100644 index 000000000000..c0abd2896ece --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bounds_check_9.f90 @@ -0,0 +1,36 @@ +! { dg-do run } +! { dg-options "-fbounds-check" } +! PR fortran/31119 +! +module sub_mod +contains +elemental subroutine set_optional(i,idef,iopt) + integer, intent(out) :: i + integer, intent(in) :: idef + integer, intent(in), optional :: iopt + if (present(iopt)) then + i = iopt + else + i = idef + end if + end subroutine set_optional + + subroutine sub(ivec) + integer, intent(in), optional :: ivec(:) + integer :: ivec_(2) + call set_optional(ivec_,(/1,2/)) + if (any (ivec_ /= (/1, 2/))) call abort + call set_optional(ivec_,(/1,2/),ivec) + if (present (ivec)) then + if (any (ivec_ /= ivec)) call abort + else + if (any (ivec_ /= (/1, 2/))) call abort + end if + end subroutine sub +end module sub_mod + +program main + use sub_mod, only: sub + call sub() + call sub((/4,5/)) +end program main diff --git a/gcc/testsuite/gfortran.dg/bounds_check_fail_2.f90 b/gcc/testsuite/gfortran.dg/bounds_check_fail_2.f90 new file mode 100644 index 000000000000..bb2c247bf311 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bounds_check_fail_2.f90 @@ -0,0 +1,39 @@ +! { dg-do run } +! { dg-options "-fbounds-check" } +! { dg-shouldfail "foo" } +! +! PR 31119 +module sub_mod +contains + elemental subroutine set_optional(i,idef,iopt) + integer, intent(out) :: i + integer, intent(in) :: idef + integer, intent(in), optional :: iopt + if (present(iopt)) then + i = iopt + else + i = idef + end if + end subroutine set_optional + + subroutine sub(ivec) + integer , intent(in), optional :: ivec(:) + integer :: ivec_(2) + call set_optional(ivec_,(/1,2/)) + if (any (ivec_ /= (/1,2/))) call abort + call set_optional(ivec_,(/1,2/),ivec) + if (present (ivec)) then + if (any (ivec_ /= ivec)) call abort + else + if (any (ivec_ /= (/1,2/))) call abort + end if + end subroutine sub +end module sub_mod + +program main + use sub_mod, only: sub + call sub() + call sub((/4,5/)) + call sub((/4/)) +end program main +! { dg-output "Fortran runtime error: Array bound mismatch" } -- GitLab