From 88fec49fbb65368451cde61064b45d3ce12a29b8 Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Tue, 17 Jun 2008 22:24:20 +0200 Subject: re PR fortran/36112 (Bounds-checking on character length not working for array-constructors) 2008-06-17 Daniel Kraft PR fortran/36112 * array.c (gfc_resolve_character_array_constructor): Check that all elements with constant character length have the same one rather than fixing it if no typespec is given, emit an error if they don't. Changed return type to "try" and return FAILURE for the case above. (gfc_resolve_array_constructor): Removed unneeded call to gfc_resolve_character_array_constructor in this function. * gfortran.h (gfc_resolve_character_array_constructor): Returns try. * trans-array.c (get_array_ctor_strlen): Return length of first element rather than last element. * resolve.c (gfc_resolve_expr): Handle FAILURE return from gfc_resolve_character_array_constructor. 2008-06-17 Daniel Kraft PR fortran/36112 * gfortran.dg/bounds_check_array_ctor_1.f90: New test. * gfortran.dg/bounds_check_array_ctor_2.f90: New test. * gfortran.dg/bounds_check_array_ctor_3.f90: New test. * gfortran.dg/bounds_check_array_ctor_4.f90: New test. * gfortran.dg/bounds_check_array_ctor_5.f90: New test. * gfortran.dg/bounds_check_array_ctor_6.f90: New test. * gfortran.dg/bounds_check_array_ctor_7.f90: New test. * gfortran.dg/bounds_check_array_ctor_8.f90: New test. * gfortran.dg/arrayio_0.f90: Fixed invalid array constructor. * gfortran.dg/char_cons_len.f90: Ditto. * gfortran.dg/char_initializer_actual.f90: Ditto. * gfortran.dg/pr15959.f90: Ditto. * gfortran.dg/transfer_simplify_2.f90: Ditto. * gfortran.dg/char_length_1.f90: Changed expected error messages. From-SVN: r136872 --- gcc/fortran/trans-array.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'gcc/fortran/trans-array.c') diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 7df192c..2a96698 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -1459,6 +1459,9 @@ get_array_ctor_all_strlen (stmtblock_t *block, gfc_expr *e, tree *len) /* Figure out the string length of a character array constructor. + If len is NULL, don't calculate the length; this happens for recursive calls + when a sub-array-constructor is an element but not at the first position, + so when we're not interested in the length. Returns TRUE if all elements are character constants. */ bool @@ -1470,16 +1473,20 @@ get_array_ctor_strlen (stmtblock_t *block, gfc_constructor * c, tree * len) if (c == NULL) { - *len = build_int_cstu (gfc_charlen_type_node, 0); + if (len) + *len = build_int_cstu (gfc_charlen_type_node, 0); return is_const; } - for (; c; c = c->next) + /* Loop over all constructor elements to find out is_const, but in len we + want to store the length of the first, not the last, element. We can + of course exit the loop as soon as is_const is found to be false. */ + for (; c && is_const; c = c->next) { switch (c->expr->expr_type) { case EXPR_CONSTANT: - if (!(*len && INTEGER_CST_P (*len))) + if (len && !(*len && INTEGER_CST_P (*len))) *len = build_int_cstu (gfc_charlen_type_node, c->expr->value.character.length); break; @@ -1491,14 +1498,19 @@ get_array_ctor_strlen (stmtblock_t *block, gfc_constructor * c, tree * len) case EXPR_VARIABLE: is_const = false; - get_array_ctor_var_strlen (c->expr, len); + if (len) + get_array_ctor_var_strlen (c->expr, len); break; default: is_const = false; - get_array_ctor_all_strlen (block, c->expr, len); + if (len) + get_array_ctor_all_strlen (block, c->expr, len); break; } + + /* After the first iteration, we don't want the length modified. */ + len = NULL; } return is_const; -- cgit v1.1