aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-array.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-05-14 02:00:27 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2009-05-14 02:00:27 +0200
commit7e2791428f91a88bfe3762fa1456f435fc25e2b0 (patch)
tree939aa9b645af6be87061269b8b1cd513bd796d30 /gcc/fortran/trans-array.c
parent00b0c19b4bbfa483925a177ed3e6ce2e1f42444b (diff)
downloadgcc-7e2791428f91a88bfe3762fa1456f435fc25e2b0.zip
gcc-7e2791428f91a88bfe3762fa1456f435fc25e2b0.tar.gz
gcc-7e2791428f91a88bfe3762fa1456f435fc25e2b0.tar.bz2
re PR fortran/39865 (ICE in gfc_conv_scalarized_array_ref)
PR fortran/39865 * io.c (resolve_tag_format): CHARACTER array in FMT= argument isn't an extension. Reject non-CHARACTER array element of assumed shape or pointer or assumed size array. * trans-array.c (array_parameter_size): New function. (gfc_conv_array_parameter): Add size argument. Call array_parameter_size if it is non-NULL. * trans-array.h (gfc_conv_array_parameter): Adjust prototype. * trans-expr.c (gfc_conv_function_call, gfc_trans_arrayfunc_assign): Adjust callers. * trans-intrinsic.c (gfc_conv_intrinsic_loc): Likewise. * trans-io.c (gfc_convert_array_to_string): Rewritten. * gfortran.dg/pr39865.f90: New test. * gfortran.dg/hollerith.f90: Don't expect errors for CHARACTER arrays in FMT=. * gfortran.dg/hollerith_f95.f90: Likewise. * gfortran.dg/hollerith6.f90: New test. * gfortran.dg/hollerith7.f90: New test. From-SVN: r147507
Diffstat (limited to 'gcc/fortran/trans-array.c')
-rw-r--r--gcc/fortran/trans-array.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index 71db46d..f4276ca 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -5339,13 +5339,41 @@ gfc_conv_expr_descriptor (gfc_se * se, gfc_expr * expr, gfc_ss * ss)
gfc_cleanup_loop (&loop);
}
+/* Helper function for gfc_conv_array_parameter if array size needs to be
+ computed. */
+
+static void
+array_parameter_size (tree desc, gfc_expr *expr, tree *size)
+{
+ tree elem;
+ if (GFC_ARRAY_TYPE_P (TREE_TYPE (desc)))
+ *size = GFC_TYPE_ARRAY_SIZE (TREE_TYPE (desc));
+ else if (expr->rank > 1)
+ *size = build_call_expr (gfor_fndecl_size0, 1,
+ gfc_build_addr_expr (NULL, desc));
+ else
+ {
+ tree ubound = gfc_conv_descriptor_ubound (desc, gfc_index_zero_node);
+ tree lbound = gfc_conv_descriptor_lbound (desc, gfc_index_zero_node);
+
+ *size = fold_build2 (MINUS_EXPR, gfc_array_index_type, ubound, lbound);
+ *size = fold_build2 (PLUS_EXPR, gfc_array_index_type, *size,
+ gfc_index_one_node);
+ *size = fold_build2 (MAX_EXPR, gfc_array_index_type, *size,
+ gfc_index_zero_node);
+ }
+ elem = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
+ *size = fold_build2 (MULT_EXPR, gfc_array_index_type, *size,
+ fold_convert (gfc_array_index_type, elem));
+}
/* Convert an array for passing as an actual parameter. */
/* TODO: Optimize passing g77 arrays. */
void
gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
- const gfc_symbol *fsym, const char *proc_name)
+ const gfc_symbol *fsym, const char *proc_name,
+ tree *size)
{
tree ptr;
tree desc;
@@ -5394,6 +5422,8 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
se->expr = tmp;
else
se->expr = gfc_build_addr_expr (NULL_TREE, tmp);
+ if (size)
+ array_parameter_size (tmp, expr, size);
return;
}
if (sym->attr.allocatable)
@@ -5401,10 +5431,11 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
if (sym->attr.dummy || sym->attr.result)
{
gfc_conv_expr_descriptor (se, expr, ss);
- se->expr = gfc_conv_array_data (se->expr);
+ tmp = se->expr;
}
- else
- se->expr = gfc_conv_array_data (tmp);
+ if (size)
+ array_parameter_size (tmp, expr, size);
+ se->expr = gfc_conv_array_data (tmp);
return;
}
}
@@ -5413,6 +5444,8 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
{
/* Result of the enclosing function. */
gfc_conv_expr_descriptor (se, expr, ss);
+ if (size)
+ array_parameter_size (se->expr, expr, size);
se->expr = gfc_build_addr_expr (NULL_TREE, se->expr);
if (g77 && TREE_TYPE (TREE_TYPE (se->expr)) != NULL_TREE
@@ -5426,6 +5459,9 @@ gfc_conv_array_parameter (gfc_se * se, gfc_expr * expr, gfc_ss * ss, int g77,
/* Every other type of array. */
se->want_pointer = 1;
gfc_conv_expr_descriptor (se, expr, ss);
+ if (size)
+ array_parameter_size (build_fold_indirect_ref (se->expr),
+ expr, size);
}
/* Deallocate the allocatable components of structures that are