aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-array.c
diff options
context:
space:
mode:
authorAndre Vehreschild <vehre@gcc.gnu.org>2016-10-25 19:01:58 +0200
committerAndre Vehreschild <vehre@gcc.gnu.org>2016-10-25 19:01:58 +0200
commitcef026ecafe169871284fded6494efe33e763950 (patch)
treeb0f80442a77baa418265d5ccf11e02c29050fe97 /gcc/fortran/trans-array.c
parent6c3b5bf0725df869a12894682068b12dbf220568 (diff)
downloadgcc-cef026ecafe169871284fded6494efe33e763950.zip
gcc-cef026ecafe169871284fded6494efe33e763950.tar.gz
gcc-cef026ecafe169871284fded6494efe33e763950.tar.bz2
re PR fortran/72770 (ICE in make_ssa_name_fn, at tree-ssanames.c:263)
gcc/testsuite/ChangeLog: 2016-10-25 Andre Vehreschild <vehre@gcc.gnu.org> PR fortran/72770 * gfortran.dg/alloc_comp_class_5.f03: Added test again that caused this pr. gcc/fortran/ChangeLog: 2016-10-25 Andre Vehreschild <vehre@gcc.gnu.org> PR fortran/72770 * class.c (find_intrinsic_vtab): No longer encode the string length into vtype's name and use the char's kind for the size instead of the string_length time the size. * trans-array.c (gfc_conv_ss_descriptor): For deferred length char arrays the dynamically sized type needs to be declared. (build_class_array_ref): Address the i-th array element by multiplying it with the _vptr->_size and the _len to make sure char arrays are addressed correctly. * trans-expr.c (gfc_conv_intrinsic_to_class): Made comment more precise. From-SVN: r241528
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r--gcc/fortran/trans-array.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 117349e..de21cc0 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -2681,6 +2681,20 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base)
if (base)
{
+ if (ss_info->expr->ts.type == BT_CHARACTER && !ss_info->expr->ts.deferred
+ && ss_info->expr->ts.u.cl->length == NULL)
+ {
+ /* Emit a DECL_EXPR for the variable sized array type in
+ GFC_TYPE_ARRAY_DATAPTR_TYPE so the gimplification of its type
+ sizes works correctly. */
+ tree arraytype = TREE_TYPE (
+ GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (info->descriptor)));
+ if (! TYPE_NAME (arraytype))
+ TYPE_NAME (arraytype) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
+ NULL_TREE, arraytype);
+ gfc_add_expr_to_block (block, build1 (DECL_EXPR, arraytype,
+ TYPE_NAME (arraytype)));
+ }
/* Also the data pointer. */
tmp = gfc_conv_array_data (se.expr);
/* If this is a variable or address of a variable we use it directly.
@@ -3143,9 +3157,22 @@ build_class_array_ref (gfc_se *se, tree base, tree index)
size = gfc_class_vtab_size_get (decl);
+ /* For unlimited polymorphic entities then _len component needs to be
+ multiplied with the size. If no _len component is present, then
+ gfc_class_len_or_zero_get () return a zero_node. */
+ tmp = gfc_class_len_or_zero_get (decl);
+ if (!integer_zerop (tmp))
+ size = fold_build2 (MULT_EXPR, TREE_TYPE (index),
+ fold_convert (TREE_TYPE (index), size),
+ fold_build2 (MAX_EXPR, TREE_TYPE (index),
+ fold_convert (TREE_TYPE (index), tmp),
+ fold_convert (TREE_TYPE (index),
+ integer_one_node)));
+ else
+ size = fold_convert (TREE_TYPE (index), size);
+
/* Build the address of the element. */
type = TREE_TYPE (TREE_TYPE (base));
- size = fold_convert (TREE_TYPE (index), size);
offset = fold_build2_loc (input_location, MULT_EXPR,
gfc_array_index_type,
index, size);