aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/expr.c
diff options
context:
space:
mode:
authorPaul Thomas <pault@gcc.gnu.org>2010-01-24 16:59:51 +0000
committerPaul Thomas <pault@gcc.gnu.org>2010-01-24 16:59:51 +0000
commitff015c5b6ca00915e35ddb373ed3f25e4e020e09 (patch)
tree52183dddc5326158a8d06309248d28ef63d0e1f9 /gcc/fortran/expr.c
parent23f6293ee8a55bcfa45caa456d86dc403315ce68 (diff)
downloadgcc-ff015c5b6ca00915e35ddb373ed3f25e4e020e09.zip
gcc-ff015c5b6ca00915e35ddb373ed3f25e4e020e09.tar.gz
gcc-ff015c5b6ca00915e35ddb373ed3f25e4e020e09.tar.bz2
re PR fortran/41044 (internal compiler error: in gfc_conv_intrinsic_function)
2010-01-24 Paul Thomas <pault@gcc.gnu.org> PR fortran/41044 PR fortran/41167 * expr.c (remove_subobject_ref): If the constructor is NULL use the expression as the source. (simplify_const_ref): Change the type of expression if there are component references. Allow for substring to be at the end of an arbitrarily long chain of references. If an element is found that is not in an EXPR_ARRAY, assume that this is scalar initialization of array. Call remove_subobject_ref in this case with NULL second argument. 2010-01-24 Paul Thomas <pault@gcc.gnu.org> PR fortran/41044 * gfortran.dg/parameter_array_ref_2.f90 : New test. PR fortran/41167 * gfortran.dg/char_array_arg_1.f90 : New test. * gfortran.dg/pr25923.f90 : Remove XFAIL. From-SVN: r156197
Diffstat (limited to 'gcc/fortran/expr.c')
-rw-r--r--gcc/fortran/expr.c42
1 files changed, 31 insertions, 11 deletions
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 8fa46d8..d846c0f 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -1154,8 +1154,13 @@ remove_subobject_ref (gfc_expr *p, gfc_constructor *cons)
{
gfc_expr *e;
- e = cons->expr;
- cons->expr = NULL;
+ if (cons)
+ {
+ e = cons->expr;
+ cons->expr = NULL;
+ }
+ else
+ e = gfc_copy_expr (p);
e->ref = p->ref->next;
p->ref->next = NULL;
gfc_replace_expr (p, e);
@@ -1464,6 +1469,7 @@ simplify_const_ref (gfc_expr *p)
{
gfc_constructor *cons;
gfc_expr *newp;
+ gfc_ref *last_ref;
while (p->ref)
{
@@ -1473,6 +1479,13 @@ simplify_const_ref (gfc_expr *p)
switch (p->ref->u.ar.type)
{
case AR_ELEMENT:
+ /* <type/kind spec>, parameter :: x(<int>) = scalar_expr
+ will generate this. */
+ if (p->expr_type != EXPR_ARRAY)
+ {
+ remove_subobject_ref (p, NULL);
+ break;
+ }
if (find_array_element (p->value.constructor, &p->ref->u.ar,
&cons) == FAILURE)
return FAILURE;
@@ -1502,18 +1515,25 @@ simplify_const_ref (gfc_expr *p)
return FAILURE;
}
- /* If this is a CHARACTER array and we possibly took a
- substring out of it, update the type-spec's character
- length according to the first element (as all should have
- the same length). */
- if (p->ts.type == BT_CHARACTER)
+ if (p->ts.type == BT_DERIVED
+ && p->ref->next
+ && p->value.constructor)
{
- int string_len;
+ /* There may have been component references. */
+ p->ts = p->value.constructor->expr->ts;
+ }
- gcc_assert (p->ref->next);
- gcc_assert (!p->ref->next->next);
- gcc_assert (p->ref->next->type == REF_SUBSTRING);
+ last_ref = p->ref;
+ for (; last_ref->next; last_ref = last_ref->next) {};
+ if (p->ts.type == BT_CHARACTER
+ && last_ref->type == REF_SUBSTRING)
+ {
+ /* If this is a CHARACTER array and we possibly took
+ a substring out of it, update the type-spec's
+ character length according to the first element
+ (as all should have the same length). */
+ int string_len;
if (p->value.constructor)
{
const gfc_expr* first = p->value.constructor->expr;