diff options
author | Daniel Kraft <d@domob.eu> | 2008-05-16 21:50:04 +0200 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2008-05-16 21:50:04 +0200 |
commit | c03fc95db39f7eefe676d2bff9a7c99b5ec01ed9 (patch) | |
tree | c7e366c619e4465a3a807a4d48e072cb8c58d1aa /gcc/fortran/trans-array.c | |
parent | c62b365920ac525ceabcfe7eb9cd6a9f9539d78c (diff) | |
download | gcc-c03fc95db39f7eefe676d2bff9a7c99b5ec01ed9.zip gcc-c03fc95db39f7eefe676d2bff9a7c99b5ec01ed9.tar.gz gcc-c03fc95db39f7eefe676d2bff9a7c99b5ec01ed9.tar.bz2 |
re PR fortran/27997 (Fortran 2003: Support type-spec for array constructor)
2008-04-16 Daniel Kraft <d@domob.eu>
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 <d@domob.eu>
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
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r-- | gcc/fortran/trans-array.c | 35 |
1 files changed, 31 insertions, 4 deletions
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. */ |