------- Comment #3 from pault at gcc dot gnu dot org 2007-05-16 20:55 -------
This fixes it and much more besides. It needs commenting and tidying up.
Paul
Index: gcc/fortran/trans-array.c
===================================================================
*** gcc/fortran/trans-array.c (révision 124762)
--- gcc/fortran/trans-array.c (copie de travail)
*************** gfc_trans_dummy_array_bias (gfc_symbol *
*** 4243,4248 ****
--- 4243,4315 ----
}
+ static void
+ gfc_fixup_missing_charlen (gfc_se *se, gfc_expr *expr)
+ {
+ tree tmp;
+ gfc_ref *char_ref = expr->ref;
+
+ expr->ts.cl = gfc_get_charlen ();
+ expr->ts.cl->next = gfc_current_ns->cl_list;
+ gfc_current_ns->cl_list = expr->ts.cl;
+ expr->ts.cl->backend_decl
+ = gfc_create_var (gfc_charlen_type_node, "cl");
+
+ for (; char_ref; char_ref = char_ref->next)
+ if (char_ref->type == REF_SUBSTRING)
+ {
+ mpz_t char_len;
+
+ mpz_init_set_ui (char_len, 1);
+ mpz_add (char_len, char_len,
+ char_ref->u.ss.end->value.integer);
+ mpz_sub (char_len, char_len,
+ char_ref->u.ss.start->value.integer);
+ tmp = gfc_conv_mpz_to_tree (char_len,
+ gfc_default_character_kind);
+ /* Cast is necessary for *-charlen refs. */
+ tmp = convert (gfc_charlen_type_node, tmp);
+
+ gfc_add_modify_expr (&se->pre, expr->ts.cl->backend_decl, tmp);
+ mpz_clear (char_len);
+ break;
+ }
+
+ if (char_ref == NULL)
+ {
+ mpz_t length;
+ tmp = NULL_TREE;
+
+ if (expr->expr_type == EXPR_CONSTANT)
+ mpz_init_set_si (length, expr->value.character.length);
+ else if (expr->expr_type == EXPR_ARRAY)
+ mpz_init_set_si (length,
+ expr->value.constructor->expr->value.character.length);
+ else if (expr->expr_type == EXPR_OP)
+ {
+ if (!expr->value.op.op1->ts.cl)
+ gfc_fixup_missing_charlen (se, expr->value.op.op1);
+ if (!expr->value.op.op2->ts.cl)
+ gfc_fixup_missing_charlen (se, expr->value.op.op2);
+ tmp = fold_build2 (PLUS_EXPR, gfc_charlen_type_node,
+ expr->value.op.op1->ts.cl->backend_decl,
+ expr->value.op.op2->ts.cl->backend_decl);
+ }
+ else
+ mpz_init_set_ui (length, 0);
+
+ if (!tmp)
+ {
+ tmp = gfc_conv_mpz_to_tree (length,
+ gfc_default_character_kind);
+ tmp = convert (gfc_charlen_type_node, tmp);
+ }
+
+ gfc_add_modify_expr (&se->pre, expr->ts.cl->backend_decl, tmp);
+ }
+ }
+
+
/* Convert an array for passing as an actual argument. Expressions and
vector subscripts are evaluated and stored in a temporary, which is then
passed. For whole arrays the descriptor is passed. For array sections
*************** gfc_conv_expr_descriptor (gfc_se * se, g
*** 4430,4463 ****
{
if (expr->ts.cl == NULL)
{
! /* This had better be a substring reference! */
! gfc_ref *char_ref = expr->ref;
! for (; char_ref; char_ref = char_ref->next)
! if (char_ref->type == REF_SUBSTRING)
! {
! mpz_t char_len;
! expr->ts.cl = gfc_get_charlen ();
! expr->ts.cl->next = char_ref->u.ss.length->next;
! char_ref->u.ss.length->next = expr->ts.cl;
!
! mpz_init_set_ui (char_len, 1);
! mpz_add (char_len, char_len,
! char_ref->u.ss.end->value.integer);
! mpz_sub (char_len, char_len,
! char_ref->u.ss.start->value.integer);
! expr->ts.cl->backend_decl
! = gfc_conv_mpz_to_tree (char_len,
! gfc_default_character_kind);
! /* Cast is necessary for *-charlen refs. */
! expr->ts.cl->backend_decl
! = convert (gfc_charlen_type_node,
! expr->ts.cl->backend_decl);
! mpz_clear (char_len);
! break;
! }
! gcc_assert (char_ref != NULL);
loop.temp_ss->data.temp.type
! = gfc_typenode_for_spec (&expr->ts);
loop.temp_ss->string_length = expr->ts.cl->backend_decl;
}
else if (expr->ts.cl->length
--- 4497,4505 ----
{
if (expr->ts.cl == NULL)
{
! gfc_fixup_missing_charlen (se, expr);
loop.temp_ss->data.temp.type
! = gfc_typenode_for_spec (&expr->ts);
loop.temp_ss->string_length = expr->ts.cl->backend_decl;
}
else if (expr->ts.cl->length
--
pault at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
AssignedTo|unassigned at gcc dot gnu |pault at gcc dot gnu dot org
|dot org |
Status|NEW |ASSIGNED
Last reconfirmed|2007-05-09 22:53:25 |2007-05-16 20:55:31
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31879