diff options
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) |