aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/trans-intrinsic.c
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2006-10-31 06:03:24 +0000
committerPaul Thomas <pault@gcc.gnu.org>2006-10-31 06:03:24 +0000
commitdd5797cc36028b51596c88d0b5ecc1f0a2902488 (patch)
treea2f3d9751ac9c0b7ae6f8b76727cb0d066e270f5 /gcc/fortran/trans-intrinsic.c
parente5c18c3c298de538f6a9acec3120b63d830dc307 (diff)
downloadgcc-dd5797cc36028b51596c88d0b5ecc1f0a2902488.zip
gcc-dd5797cc36028b51596c88d0b5ecc1f0a2902488.tar.gz
gcc-dd5797cc36028b51596c88d0b5ecc1f0a2902488.tar.bz2
re PR fortran/29387 (ICE on character array function of variable length)
2006-10-31 Paul Thomas <pault@gcc.gnu.org> PR fortran/29387 * trans-intrinsic.c (gfc_conv_intrinsic_len): Rearrange to have a specific case for EXPR_VARIABLE and, in default, build an ss to call gfc_conv_expr_descriptor for array expressions.. PR fortran/29490 * trans-expr.c (gfc_set_interface_mapping_bounds): In the case that GFC_TYPE_ARRAY_LBOUND is not available, use descriptor values for it and GFC_TYPE_ARRAY_UBOUND. PR fortran/29641 * trans-types.c (gfc_get_derived_type): If the derived type namespace has neither a parent nor a proc_name, set NULL for the search namespace. 2006-10-31 Paul Thomas <pault@gcc.gnu.org> PR fortran/29387 * gfortran.dg/intrinsic_actual_2.f90: New test. PR fortran/29490 * gfortran.dg/actual_array_interface_1.f90: New test. PR fortran/29641 * gfortran.dg/used_types_11.f90: New test. From-SVN: r118220
Diffstat (limited to 'gcc/fortran/trans-intrinsic.c')
-rw-r--r--gcc/fortran/trans-intrinsic.c57
1 files changed, 31 insertions, 26 deletions
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 44d439d..d031878 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -2429,6 +2429,7 @@ gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
gfc_symbol *sym;
gfc_se argse;
gfc_expr *arg;
+ gfc_ss *ss;
gcc_assert (!se->ss);
@@ -2448,32 +2449,37 @@ gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
get_array_ctor_strlen (arg->value.constructor, &len);
break;
- default:
- if (arg->expr_type == EXPR_VARIABLE
- && (arg->ref == NULL || (arg->ref->next == NULL
- && arg->ref->type == REF_ARRAY)))
- {
- /* This doesn't catch all cases.
- See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
- and the surrounding thread. */
- sym = arg->symtree->n.sym;
- decl = gfc_get_symbol_decl (sym);
- if (decl == current_function_decl && sym->attr.function
+ case EXPR_VARIABLE:
+ if (arg->ref == NULL
+ || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
+ {
+ /* This doesn't catch all cases.
+ See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
+ and the surrounding thread. */
+ sym = arg->symtree->n.sym;
+ decl = gfc_get_symbol_decl (sym);
+ if (decl == current_function_decl && sym->attr.function
&& (sym->result == sym))
- decl = gfc_get_fake_result_decl (sym, 0);
-
- len = sym->ts.cl->backend_decl;
- gcc_assert (len);
- }
- else
- {
- /* Anybody stupid enough to do this deserves inefficient code. */
- gfc_init_se (&argse, se);
- gfc_conv_expr (&argse, arg);
- gfc_add_block_to_block (&se->pre, &argse.pre);
- gfc_add_block_to_block (&se->post, &argse.post);
- len = argse.string_length;
+ decl = gfc_get_fake_result_decl (sym, 0);
+
+ len = sym->ts.cl->backend_decl;
+ gcc_assert (len);
+ break;
}
+
+ /* Otherwise fall through. */
+
+ default:
+ /* Anybody stupid enough to do this deserves inefficient code. */
+ ss = gfc_walk_expr (arg);
+ gfc_init_se (&argse, se);
+ if (ss == gfc_ss_terminator)
+ gfc_conv_expr (&argse, arg);
+ else
+ gfc_conv_expr_descriptor (&argse, arg, ss);
+ gfc_add_block_to_block (&se->pre, &argse.pre);
+ gfc_add_block_to_block (&se->post, &argse.post);
+ len = argse.string_length;
break;
}
se->expr = convert (type, len);
@@ -3020,8 +3026,7 @@ gfc_conv_associated (gfc_se *se, gfc_expr *expr)
else
{
/* A pointer to an array. */
- arg1se.descriptor_only = 1;
- gfc_conv_expr_lhs (&arg1se, arg1->expr);
+ gfc_conv_expr_descriptor (&arg1se, arg1->expr, ss1);
tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
}
gfc_add_block_to_block (&se->pre, &arg1se.pre);