diff options
author | Paul Thomas <pault@gcc.gnu.org> | 2018-09-30 12:22:07 +0000 |
---|---|---|
committer | Paul Thomas <pault@gcc.gnu.org> | 2018-09-30 12:22:07 +0000 |
commit | ba08c70a0c73b9fef5b78e2e5706845aa85c4df7 (patch) | |
tree | 52932d1b845b28c268d7a49e53166ffcfb5b5e55 /gcc/fortran/trans-array.c | |
parent | f1525dd4b4c4e57e8dd6f1c1a90f1a148b3da945 (diff) | |
download | gcc-ba08c70a0c73b9fef5b78e2e5706845aa85c4df7.zip gcc-ba08c70a0c73b9fef5b78e2e5706845aa85c4df7.tar.gz gcc-ba08c70a0c73b9fef5b78e2e5706845aa85c4df7.tar.bz2 |
re PR fortran/70752 (Incorrect LEN for ALLOCATABLE CHARACTER)
2018-09-30 Paul Thomas <pault@gcc.gnu.org>
PR fortran/70752
PR fortran/72709
* trans-array.c (gfc_conv_scalarized_array_ref): If this is a
deferred type and the info->descriptor is present, use the
info->descriptor
(gfc_conv_array_ref): Is the se expr is a descriptor type, pass
it as 'decl' rather than the symbol backend_decl.
(gfc_array_allocate): If the se string_length is a component
reference, fix it and use it for the expression string length
if the latter is not a variable type. If it is a variable do
an assignment. Make use of component ref string lengths to set
the descriptor 'span'.
(gfc_conv_expr_descriptor): For pointer assignment, do not set
the span field if gfc_get_array_span returns zero.
* trans.c (get_array_span): If the upper bound a character type
is zero, use the descriptor span if available.
2018-09-30 Paul Thomas <pault@gcc.gnu.org>
PR fortran/70752
PR fortran/72709
* gfortran.dg/deferred_character_25.f90 : New test.
* gfortran.dg/deferred_character_26.f90 : New test.
* gfortran.dg/deferred_character_27.f90 : New test to verify
that PR82617 remains fixed.
From-SVN: r264724
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r-- | gcc/fortran/trans-array.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index 0d699ed..035257a 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -3423,7 +3423,9 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar) /* A pointer array component can be detected from its field decl. Fix the descriptor, mark the resulting variable decl and pass it to gfc_build_array_ref. */ - if (is_pointer_array (info->descriptor)) + if (is_pointer_array (info->descriptor) + || (expr && expr->ts.deferred && info->descriptor + && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (info->descriptor)))) { if (TREE_CODE (info->descriptor) == COMPONENT_REF) decl = info->descriptor; @@ -3676,7 +3678,16 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, else if (expr->ts.deferred || (sym->ts.type == BT_CHARACTER && sym->attr.select_type_temporary)) - decl = sym->backend_decl; + { + if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr))) + { + decl = se->expr; + if (TREE_CODE (decl) == INDIRECT_REF) + decl = TREE_OPERAND (decl, 0); + } + else + decl = sym->backend_decl; + } else if (sym->ts.type == BT_CLASS) decl = NULL_TREE; @@ -5761,6 +5772,19 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, overflow = integer_zero_node; + if (expr->ts.type == BT_CHARACTER + && TREE_CODE (se->string_length) == COMPONENT_REF + && expr->ts.u.cl->backend_decl != se->string_length) + { + if (VAR_P (expr->ts.u.cl->backend_decl)) + gfc_add_modify (&se->pre, expr->ts.u.cl->backend_decl, + fold_convert (TREE_TYPE (expr->ts.u.cl->backend_decl), + se->string_length)); + else + expr->ts.u.cl->backend_decl = gfc_evaluate_now (se->string_length, + &se->pre); + } + gfc_init_block (&set_descriptor_block); /* Take the corank only from the actual ref and not from the coref. The later will mislead the generation of the array dimensions for allocatable/ @@ -5850,10 +5874,26 @@ gfc_array_allocate (gfc_se * se, gfc_expr * expr, tree status, tree errmsg, /* Pointer arrays need the span field to be set. */ if (is_pointer_array (se->expr) || (expr->ts.type == BT_CLASS - && CLASS_DATA (expr)->attr.class_pointer)) + && CLASS_DATA (expr)->attr.class_pointer) + || (expr->ts.type == BT_CHARACTER + && TREE_CODE (se->string_length) == COMPONENT_REF)) { if (expr3 && expr3_elem_size != NULL_TREE) tmp = expr3_elem_size; + else if (se->string_length + && TREE_CODE (se->string_length) == COMPONENT_REF) + { + if (expr->ts.kind != 1) + { + tmp = build_int_cst (gfc_array_index_type, expr->ts.kind); + tmp = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, tmp, + fold_convert (gfc_array_index_type, + se->string_length)); + } + else + tmp = se->string_length; + } else tmp = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (se->expr))); tmp = fold_convert (gfc_array_index_type, tmp); @@ -7086,7 +7126,7 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) /* ....and set the span field. */ tmp = gfc_get_array_span (desc, expr); - if (tmp != NULL_TREE) + if (tmp != NULL_TREE && !integer_zerop (tmp)) gfc_conv_descriptor_span_set (&se->pre, se->expr, tmp); } else if (se->want_pointer) |