From c03fc95db39f7eefe676d2bff9a7c99b5ec01ed9 Mon Sep 17 00:00:00 2001 From: Daniel Kraft Date: Fri, 16 May 2008 21:50:04 +0200 Subject: re PR fortran/27997 (Fortran 2003: Support type-spec for array constructor) 2008-04-16 Daniel Kraft PR fortran/27997 * gfortran.h: Added field "length_from_typespec" to gfc_charlength. * aray.c (gfc_match_array_constructor): Added code to parse * typespec. (check_element_type, check_constructor_type, gfc_check_constructor_type): Extended to support explicit typespec on constructor. (gfc_resolve_character_array_constructor): Pad strings correctly for explicit, constant character length. * trans-array.c: New static global variable * "typespec_chararray_ctor" (gfc_trans_array_constructor): New code to support explicit but dynamic character lengths. 2008-04-16 Daniel Kraft PR fortran/27997 * gfortran.dg/array_constructor_type_1.f03: New test * gfortran.dg/array_constructor_type_2.f03: New test * gfortran.dg/array_constructor_type_3.f03: New test * gfortran.dg/array_constructor_type_4.f03: New test * gfortran.dg/array_constructor_type_5.f03: New test * gfortran.dg/array_constructor_type_6.f03: New test * gfortran.dg/array_constructor_type_7.f03: New test * gfortran.dg/array_constructor_type_8.f03: New test * gfortran.dg/array_constructor_type_9.f: New test * gfortran.dg/array_constructor_type_10.f03: New test * gfortran.dg/array_constructor_type_11.f03: New test * gfortran.dg/array_constructor_type_12.f03: New test * gfortran.dg/array_constructor_type_13.f90: New test * gfortran.dg/array_constructor_type_14.f03: New test * gfortran.dg/array_constructor_type_15.f03: New test * gfortran.dg/array_constructor_type_16.f03: New test * gfortran.dg/array_constructor_type_17.f03: New test * gfortran.dg/array_constructor_type_18.f03: New test From-SVN: r135439 --- gcc/fortran/trans-array.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) (limited to 'gcc/fortran/trans-array.c') diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 3c099dd..d6464ca 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -959,9 +959,10 @@ gfc_put_offset_into_var (stmtblock_t * pblock, tree * poffset, } -/* Assign an element of an array constructor. */ +/* Variables needed for bounds-checking. */ static bool first_len; static tree first_len_val; +static bool typespec_chararray_ctor; static void gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc, @@ -998,7 +999,7 @@ gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc, se->string_length, se->expr); } - if (flag_bounds_check) + if (flag_bounds_check && !typespec_chararray_ctor) { if (first_len) { @@ -1677,7 +1678,13 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss) tree loopfrom; bool dynamic; - if (flag_bounds_check && ss->expr->ts.type == BT_CHARACTER) + /* Do bounds-checking here and in gfc_trans_array_ctor_element only if no + typespec was given for the array constructor. */ + typespec_chararray_ctor = (ss->expr->ts.cl + && ss->expr->ts.cl->length_from_typespec); + + if (flag_bounds_check && ss->expr->ts.type == BT_CHARACTER + && !typespec_chararray_ctor) { first_len_val = gfc_create_var (gfc_charlen_type_node, "len"); first_len = true; @@ -1688,7 +1695,27 @@ gfc_trans_array_constructor (gfc_loopinfo * loop, gfc_ss * ss) c = ss->expr->value.constructor; if (ss->expr->ts.type == BT_CHARACTER) { - bool const_string = get_array_ctor_strlen (&loop->pre, c, &ss->string_length); + bool const_string; + + /* get_array_ctor_strlen walks the elements of the constructor, if a + typespec was given, we already know the string length and want the one + specified there. */ + if (typespec_chararray_ctor && ss->expr->ts.cl->length + && ss->expr->ts.cl->length->expr_type != EXPR_CONSTANT) + { + gfc_se length_se; + + const_string = false; + gfc_init_se (&length_se, NULL); + gfc_conv_expr_type (&length_se, ss->expr->ts.cl->length, + gfc_charlen_type_node); + ss->string_length = length_se.expr; + gfc_add_block_to_block (&loop->pre, &length_se.pre); + gfc_add_block_to_block (&loop->post, &length_se.post); + } + else + const_string = get_array_ctor_strlen (&loop->pre, c, + &ss->string_length); /* Complex character array constructors should have been taken care of and not end up here. */ -- cgit v1.1