aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-array.c
diff options
context:
space:
mode:
authorDaniel Kraft <d@domob.eu>2008-06-17 22:24:20 +0200
committerDaniel Kraft <domob@gcc.gnu.org>2008-06-17 22:24:20 +0200
commit88fec49fbb65368451cde61064b45d3ce12a29b8 (patch)
tree5c2c5289e8a828727de4afdeb3de36331297bdc3 /gcc/fortran/trans-array.c
parent9d5c21c1f0bc3888f494dc9114e27570646c0a8f (diff)
downloadgcc-88fec49fbb65368451cde61064b45d3ce12a29b8.zip
gcc-88fec49fbb65368451cde61064b45d3ce12a29b8.tar.gz
gcc-88fec49fbb65368451cde61064b45d3ce12a29b8.tar.bz2
re PR fortran/36112 (Bounds-checking on character length not working for array-constructors)
2008-06-17 Daniel Kraft <d@domob.eu> 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 <d@domob.eu> 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
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r--gcc/fortran/trans-array.c22
1 files changed, 17 insertions, 5 deletions
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;