This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch, fortran] PR42783 - [4.5 Regression] Bogus Array bounds violation with optional array argument
- From: Paul Richard Thomas <paul dot richard dot thomas at gmail dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, fortran at gcc dot gnu dot org
- Date: Tue, 19 Jan 2010 06:54:37 +0100
- Subject: [Patch, fortran] PR42783 - [4.5 Regression] Bogus Array bounds violation with optional array argument
The disappearance of this problem is a dead give away. Testing the
presence of the optional argument by testing that the symbol's
backend_decl is NULL cannot work, since this is copied from the dummy
argument only when it is present. At -O2 and higher, this conditional
copying is eliminated and so the problem disappears.
gfc_conv_expr_present should be used instead.
I am not sure whether or not I have fixed PR42772 but I have certainly
prevented the trivial problem. Perhaps Manfred could let us know,
please?
Bootstrapped and regtested FC9/x86_64 - OK for trunk?
Cheers
Paul
2010-01-19 Paul Thomas <pault@gcc.gnu.org>
PR fortran/42783
* trans-decl.c (add_argument_checking): Do not use the backend
decl directly to test for the presence of an optional dummy
argument. Use gfc_conv_expr_present, remembering to set the
symbol referenced.
PR fortran/42772
* trans-decl.c (gfc_generate_function_code): Small white space
changes. If 'recurcheckvar' is NULL do not try to reset it.
2010-01-19 Paul Thomas <pault@gcc.gnu.org>
PR fortran/42783
* gfortran.dg/bounds_check_15.f90 : New test.
Index: gcc/fortran/trans-decl.c
===================================================================
*** gcc/fortran/trans-decl.c (revision 155875)
--- gcc/fortran/trans-decl.c (working copy)
*************** add_argument_checking (stmtblock_t *bloc
*** 3999,4006 ****
cl->passed_length,
fold_convert (gfc_charlen_type_node,
integer_zero_node));
! not_absent = fold_build2 (NE_EXPR, boolean_type_node,
! fsym->backend_decl, null_pointer_node);
absent_failed = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
not_0length, not_absent);
--- 3999,4007 ----
cl->passed_length,
fold_convert (gfc_charlen_type_node,
integer_zero_node));
! /* The symbol needs to be referenced for gfc_get_symbol_decl. */
! fsym->attr.referenced = 1;
! not_absent = gfc_conv_expr_present (fsym);
absent_failed = fold_build2 (TRUTH_OR_EXPR, boolean_type_node,
not_0length, not_absent);
*************** gfc_generate_function_code (gfc_namespac
*** 4256,4262 ****
stmtblock_t block;
stmtblock_t body;
tree result;
! tree recurcheckvar = NULL;
gfc_symbol *sym;
int rank;
bool is_recursive;
--- 4257,4263 ----
stmtblock_t block;
stmtblock_t body;
tree result;
! tree recurcheckvar = NULL_TREE;
gfc_symbol *sym;
int rank;
bool is_recursive;
*************** gfc_generate_function_code (gfc_namespac
*** 4330,4337 ****
is_recursive = sym->attr.recursive
|| (sym->attr.entry_master
&& sym->ns->entries->sym->attr.recursive);
! if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !is_recursive
! && !gfc_option.flag_recursive)
{
char * msg;
--- 4331,4339 ----
is_recursive = sym->attr.recursive
|| (sym->attr.entry_master
&& sym->ns->entries->sym->attr.recursive);
! if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
! && !is_recursive
! && !gfc_option.flag_recursive)
{
char * msg;
*************** gfc_generate_function_code (gfc_namespac
*** 4348,4354 ****
}
if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
! && sym->attr.subroutine)
{
tree alternate_return;
alternate_return = gfc_get_fake_result_decl (sym, 0);
--- 4350,4356 ----
}
if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node
! && sym->attr.subroutine)
{
tree alternate_return;
alternate_return = gfc_get_fake_result_decl (sym, 0);
*************** gfc_generate_function_code (gfc_namespac
*** 4395,4402 ****
else
result = sym->result->backend_decl;
! if (result != NULL_TREE && sym->attr.function
! && !sym->attr.pointer)
{
if (sym->ts.type == BT_DERIVED
&& sym->ts.u.derived->attr.alloc_comp)
--- 4397,4405 ----
else
result = sym->result->backend_decl;
! if (result != NULL_TREE
! && sym->attr.function
! && !sym->attr.pointer)
{
if (sym->ts.type == BT_DERIVED
&& sym->ts.u.derived->attr.alloc_comp)
*************** gfc_generate_function_code (gfc_namespac
*** 4413,4420 ****
gfc_add_expr_to_block (&block, tmp);
/* Reset recursion-check variable. */
! if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !is_recursive
! && !gfc_option.flag_openmp)
{
gfc_add_modify (&block, recurcheckvar, boolean_false_node);
recurcheckvar = NULL;
--- 4416,4425 ----
gfc_add_expr_to_block (&block, tmp);
/* Reset recursion-check variable. */
! if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
! && !is_recursive
! && !gfc_option.flag_openmp
! && recurcheckvar != NULL_TREE)
{
gfc_add_modify (&block, recurcheckvar, boolean_false_node);
recurcheckvar = NULL;
*************** gfc_generate_function_code (gfc_namespac
*** 4445,4456 ****
{
gfc_add_expr_to_block (&block, tmp);
/* Reset recursion-check variable. */
! if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION) && !is_recursive
! && !gfc_option.flag_openmp)
! {
! gfc_add_modify (&block, recurcheckvar, boolean_false_node);
! recurcheckvar = NULL;
! }
}
--- 4450,4463 ----
{
gfc_add_expr_to_block (&block, tmp);
/* Reset recursion-check variable. */
! if ((gfc_option.rtcheck & GFC_RTCHECK_RECURSION)
! && !is_recursive
! && !gfc_option.flag_openmp
! && recurcheckvar != NULL_TREE)
! {
! gfc_add_modify (&block, recurcheckvar, boolean_false_node);
! recurcheckvar = NULL_TREE;
! }
}