summaryrefslogtreecommitdiff
path: root/gcc/fortran/array.c
diff options
context:
space:
mode:
authorpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2006-07-04 20:15:52 +0000
committerpault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>2006-07-04 20:15:52 +0000
commit35d9c496f5ed92600ed9985b2a2a45516a0a002d (patch)
tree2463384e73151c98e251c62c5a975477a2bbcc92 /gcc/fortran/array.c
parentdb12dec9c543f40d6bf12a205ea118feade8b4d0 (diff)
downloadgcc-35d9c496f5ed92600ed9985b2a2a45516a0a002d.tar.gz
2006-07-04 Paul Thomas <pault@gcc.gnu.org>
PR fortran/28174 * trans-array.c (gfc_conv_expr_descriptor): When building temp, ensure that the substring reference uses a new charlen. * trans-expr.c (gfc_conv_aliased_arg): Add the formal intent to the argument list, lift the treatment of missing string lengths from the above and implement the use of the intent. (gfc_conv_function_call): Add the extra argument to the call to the above. PR fortran/28167 * trans-array.c (get_array_ctor_var_strlen): Treat a constant substring reference. * array.c (gfc_resolve_character_array_constructor): Remove static attribute and add the gfc_ prefix, make use of element charlens for the expression and pick up constant string lengths for expressions that are not themselves constant. * gfortran.h : resolve_character_array_constructor prototype added. * resolve.c (gfc_resolve_expr): Call resolve_character_array_ constructor again after expanding the constructor, to ensure that the character length is passed to the expression. 2006-07-04 Paul Thomas <pault@gcc.gnu.org> PR fortran/28174 * gfortran.dg/actual_array_substr_2.f90: New test. PR fortran/28167 * gfortran.dg/actual_array_constructor_2.f90: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@115182 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/array.c')
-rw-r--r--gcc/fortran/array.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index 2cb34994562..fa38ab9c956 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -1518,8 +1518,8 @@ resolve_array_list (gfc_constructor * p)
not specified character length, update character length to the maximum of
its element constructors' length. */
-static void
-resolve_character_array_constructor (gfc_expr * expr)
+void
+gfc_resolve_character_array_constructor (gfc_expr * expr)
{
gfc_constructor * p;
int max_length;
@@ -1531,20 +1531,53 @@ resolve_character_array_constructor (gfc_expr * expr)
if (expr->ts.cl == NULL)
{
+ for (p = expr->value.constructor; p; p = p->next)
+ if (p->expr->ts.cl != NULL)
+ {
+ /* Ensure that if there is a char_len around that it is
+ used; otherwise the middle-end confuses them! */
+ expr->ts.cl = p->expr->ts.cl;
+ goto got_charlen;
+ }
+
expr->ts.cl = gfc_get_charlen ();
expr->ts.cl->next = gfc_current_ns->cl_list;
gfc_current_ns->cl_list = expr->ts.cl;
}
+got_charlen:
+
if (expr->ts.cl->length == NULL)
{
/* Find the maximum length of the elements. Do nothing for variable array
- constructor. */
+ constructor, unless the character length is constant or there is a
+ constant substring reference. */
+
for (p = expr->value.constructor; p; p = p->next)
- if (p->expr->expr_type == EXPR_CONSTANT)
- max_length = MAX (p->expr->value.character.length, max_length);
- else
- return;
+ {
+ gfc_ref *ref;
+ for (ref = p->expr->ref; ref; ref = ref->next)
+ if (ref->type == REF_SUBSTRING
+ && ref->u.ss.start->expr_type == EXPR_CONSTANT
+ && ref->u.ss.end->expr_type == EXPR_CONSTANT)
+ break;
+
+ if (p->expr->expr_type == EXPR_CONSTANT)
+ max_length = MAX (p->expr->value.character.length, max_length);
+
+ else if (ref)
+ max_length = MAX ((int)(mpz_get_ui (ref->u.ss.end->value.integer)
+ - mpz_get_ui (ref->u.ss.start->value.integer))
+ + 1, max_length);
+
+ else if (p->expr->ts.cl && p->expr->ts.cl->length
+ && p->expr->ts.cl->length->expr_type == EXPR_CONSTANT)
+ max_length = MAX ((int)mpz_get_si (p->expr->ts.cl->length->value.integer),
+ max_length);
+
+ else
+ return;
+ }
if (max_length != -1)
{
@@ -1552,7 +1585,8 @@ resolve_character_array_constructor (gfc_expr * expr)
expr->ts.cl->length = gfc_int_expr (max_length);
/* Update the element constructors. */
for (p = expr->value.constructor; p; p = p->next)
- gfc_set_constant_character_len (max_length, p->expr);
+ if (p->expr->expr_type == EXPR_CONSTANT)
+ gfc_set_constant_character_len (max_length, p->expr);
}
}
}
@@ -1568,7 +1602,7 @@ gfc_resolve_array_constructor (gfc_expr * expr)
if (t == SUCCESS)
t = gfc_check_constructor_type (expr);
if (t == SUCCESS && expr->ts.type == BT_CHARACTER)
- resolve_character_array_constructor (expr);
+ gfc_resolve_character_array_constructor (expr);
return t;
}