aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-array.c
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2018-09-30 12:22:07 +0000
committerPaul Thomas <pault@gcc.gnu.org>2018-09-30 12:22:07 +0000
commitba08c70a0c73b9fef5b78e2e5706845aa85c4df7 (patch)
tree52932d1b845b28c268d7a49e53166ffcfb5b5e55 /gcc/fortran/trans-array.c
parentf1525dd4b4c4e57e8dd6f1c1a90f1a148b3da945 (diff)
downloadgcc-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.c48
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)