diff options
author | Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2008-03-08 18:22:31 +0000 |
---|---|---|
committer | François-Xavier Coudert <fxcoudert@gcc.gnu.org> | 2008-03-08 18:22:31 +0000 |
commit | ba4698e168aa270ac9ba50ecd2069ec7fa667613 (patch) | |
tree | de6918cf06c1ef738d8401fd78e93b50f180c2dd | |
parent | 9e94c78f82fca1cffc8b548bcd54189e27cd7ac4 (diff) | |
download | gcc-ba4698e168aa270ac9ba50ecd2069ec7fa667613.zip gcc-ba4698e168aa270ac9ba50ecd2069ec7fa667613.tar.gz gcc-ba4698e168aa270ac9ba50ecd2069ec7fa667613.tar.bz2 |
re PR fortran/34956 (-fbounds-check: bounds_check_9.f90: Use of uninitialized memory)
PR fortran/34956
* trans-array.c (gfc_conv_ss_startstride): Fix the logic to avoid
checking bounds of absent optional arguments.
From-SVN: r133037
-rw-r--r-- | gcc/fortran/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fortran/trans-array.c | 44 |
2 files changed, 30 insertions, 20 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 51aeeaf..8356108 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2008-03-08 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> + + PR fortran/34956 + * trans-array.c (gfc_conv_ss_startstride): Fix the logic to avoid + checking bounds of absent optional arguments. + 2008-03-06 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> PR fortran/33197 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 07b0f60..542e22f 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -2924,9 +2924,13 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) 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; @@ -2953,7 +2957,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) 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; @@ -2995,7 +2999,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) 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, @@ -3011,7 +3015,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) 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); @@ -3033,7 +3037,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) 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, @@ -3048,7 +3052,7 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) 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); @@ -3066,30 +3070,30 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop) 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); |