The following only fails if -fbounds-check are turned on. ./bounds_check_9.f90 ==29980== Conditional jump or move depends on uninitialised value(s) ==29980== at 0x4008BD: __sub_mod_MOD_sub (bounds_check_9.f90:23) ==29980== by 0x400C72: MAIN__ (bounds_check_9.f90:34) [...] ./bounds_check_fail_2.f90 ==29996== Conditional jump or move depends on uninitialised value(s) ==29996== at 0x4008BD: __sub_mod_MOD_sub (bounds_check_fail_2.f90:24) ==29996== by 0x400C72: MAIN__ (bounds_check_fail_2.f90:35) ==29996== by 0x400D1B: main (fmain.c:21) [...]
Reduced testcase: $ cat bounds_check_9.f90 program main call sub() contains subroutine set_optional(iopt) integer, optional :: iopt(:) end subroutine set_optional subroutine sub(ivec) integer, optional :: ivec(:) call set_optional(ivec) end subroutine sub end program main $ gfortran -fbounds-check bounds_check_9.f90 -g && valgrind ./a.out ==10896== Memcheck, a memory error detector. ==10896== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==10896== Using LibVEX rev 1658, a library for dynamic binary translation. ==10896== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==10896== Using valgrind-3.2.1-Debian, a dynamic binary instrumentation framework. ==10896== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==10896== For more details, rerun with: -v ==10896== ==10896== Conditional jump or move depends on uninitialised value(s) ==10896== at 0x400375: sub.923 (bounds_check_9.f90:9) ==10896== by 0x4002C3: MAIN__ (bounds_check_9.f90:2) ==10896== by 0x40049B: main (fmain.c:21) ==10896== ==10896== Conditional jump or move depends on uninitialised value(s) ==10896== at 0x4003B0: sub.923 (bounds_check_9.f90:9) ==10896== by 0x4002C3: MAIN__ (bounds_check_9.f90:2) ==10896== by 0x40049B: main (fmain.c:21) ==10896== ==10896== Conditional jump or move depends on uninitialised value(s) ==10896== at 0x4003EE: sub.923 (bounds_check_9.f90:9) ==10896== by 0x4002C3: MAIN__ (bounds_check_9.f90:2) ==10896== by 0x40049B: main (fmain.c:21) ==10896== ==10896== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 1 from 1) ==10896== malloc/free: in use at exit: 0 bytes in 0 blocks. ==10896== malloc/free: 0 allocs, 0 frees, 0 bytes allocated. ==10896== For counts of detected errors, rerun with: -v ==10896== All heap blocks were freed -- no leaks are possible.
The following patch fixes it, but I don't know yet if it regtests... Index: trans-array.c =================================================================== --- trans-array.c (revision 132578) +++ trans-array.c (working copy) @@ -2912,9 +2912,13 @@ for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain) { + stmtblock_t inner; + if (ss->type != GFC_SS_SECTION) continue; + gfc_start_block (&inner); + /* TODO: range checking for mapped dimensions. */ info = &ss->data.info; @@ -2941,7 +2945,7 @@ asprintf (&msg, "Zero stride is not allowed, for dimension %d " "of array '%s'", info->dim[n]+1, ss->expr->symtree->name); - gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg); + gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg); gfc_free (msg); desc = ss->data.info.descriptor; @@ -2983,7 +2987,7 @@ asprintf (&msg, "%s, lower bound of dimension %d of array '%s'" " exceeded (%%ld < %%ld)", gfc_msg_fault, info->dim[n]+1, ss->expr->symtree->name); - gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg, + gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg, fold_convert (long_integer_type_node, info->start[n]), fold_convert (long_integer_type_node, @@ -2999,7 +3003,7 @@ asprintf (&msg, "%s, upper bound of dimension %d of array " "'%s' exceeded (%%ld > %%ld)", gfc_msg_fault, info->dim[n]+1, ss->expr->symtree->name); - gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg, + gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg, fold_convert (long_integer_type_node, info->start[n]), fold_convert (long_integer_type_node, ubound)); gfc_free (msg); @@ -3021,7 +3025,7 @@ asprintf (&msg, "%s, lower bound of dimension %d of array '%s'" " exceeded (%%ld < %%ld)", gfc_msg_fault, info->dim[n]+1, ss->expr->symtree->name); - gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg, + gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg, fold_convert (long_integer_type_node, tmp2), fold_convert (long_integer_type_node, @@ -3036,7 +3040,7 @@ asprintf (&msg, "%s, upper bound of dimension %d of array " "'%s' exceeded (%%ld > %%ld)", gfc_msg_fault, info->dim[n]+1, ss->expr->symtree->name); - gfc_trans_runtime_check (tmp, &block, &ss->expr->where, msg, + gfc_trans_runtime_check (tmp, &inner, &ss->expr->where, msg, fold_convert (long_integer_type_node, tmp2), fold_convert (long_integer_type_node, ubound)); gfc_free (msg); @@ -3054,30 +3058,30 @@ 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); - gfc_trans_runtime_check (tmp3, &block, &ss->expr->where, msg, + gfc_trans_runtime_check (tmp3, &inner, &ss->expr->where, msg, fold_convert (long_integer_type_node, tmp), fold_convert (long_integer_type_node, size[n])); gfc_free (msg); } else - size[n] = gfc_evaluate_now (tmp, &block); + size[n] = gfc_evaluate_now (tmp, &inner); } + + tmp = gfc_finish_block (&inner); + + /* 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) + tmp = build3_v (COND_EXPR, + gfc_conv_expr_present (ss->expr->symtree->n.sym), + tmp, build_empty_stmt ()); + + gfc_add_expr_to_block (&block, tmp); + } tmp = gfc_finish_block (&block);
Subject: Bug 34956 Author: fxcoudert Date: Sat Mar 8 18:22:31 2008 New Revision: 133037 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=133037 Log: PR fortran/34956 * trans-array.c (gfc_conv_ss_startstride): Fix the logic to avoid checking bounds of absent optional arguments. Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/trans-array.c
Fixed on mainline.