This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR fortran/91552 -- Walk array constructor to do type conversion
- From: Steve Kargl <sgk at troutmask dot apl dot washington dot edu>
- To: fortran at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Sat, 31 Aug 2019 13:15:44 -0700
- Subject: [PATCH] PR fortran/91552 -- Walk array constructor to do type conversion
- Reply-to: sgk at troutmask dot apl dot washington dot edu
The attached patch has been built and tested on i586-*-freebsd
and x86_64-*-freebsd. OK to commit?
The patch fixes an ICE during type conversion where an array
constructor contains another array. The new function recursively
walks the constructor, and tries to do the type conversion.
The testcase demonstrates the recursion.
2019-08-31 Steven G. Kargl <kargl@gc.gnu.org>
PR fortran/91552
* array.c (walk_array_constructor): New function.
(gfc_match_array_constructor): Use it.
2019-08-31 Steven G. Kargl <kargl@gc.gnu.org>
PR fortran/91552
* gfortran.dg/pr91552.f90: New test.
--
Steve
Index: gcc/fortran/array.c
===================================================================
--- gcc/fortran/array.c (revision 275235)
+++ gcc/fortran/array.c (working copy)
@@ -1134,6 +1134,31 @@ done:
}
+/* Convert components of an array constructor to the type in ts. */
+
+static match
+walk_array_constructor (gfc_typespec *ts, gfc_constructor_base head)
+{
+ gfc_constructor *c;
+ gfc_expr *e;
+ match m;
+
+ for (c = gfc_constructor_first (head); c; c = gfc_constructor_next (c))
+ {
+ e = c->expr;
+ if (e->expr_type == EXPR_ARRAY && e->ts.type == BT_UNKNOWN
+ && !e->ref && e->value.constructor)
+ {
+ m = walk_array_constructor (ts, e->value.constructor);
+ if (m == MATCH_ERROR)
+ return m;
+ }
+ else if (!gfc_convert_type (e, ts, 1) && e->ts.type != BT_UNKNOWN)
+ return MATCH_ERROR;
+ }
+ return MATCH_YES;
+}
+
/* Match an array constructor. */
match
@@ -1263,14 +1288,13 @@ done:
}
}
- /* Walk the constructor and ensure type conversion for numeric types. */
+ /* Walk the constructor, and if possible, do type conversion for
+ numeric types. */
if (gfc_numeric_ts (&ts))
{
- c = gfc_constructor_first (head);
- for (; c; c = gfc_constructor_next (c))
- if (!gfc_convert_type (c->expr, &ts, 1)
- && c->expr->ts.type != BT_UNKNOWN)
- return MATCH_ERROR;
+ m = walk_array_constructor (&ts, head);
+ if (m == MATCH_ERROR)
+ return m;
}
}
else
Index: gcc/testsuite/gfortran.dg/pr91552.f90
===================================================================
--- gcc/testsuite/gfortran.dg/pr91552.f90 (nonexistent)
+++ gcc/testsuite/gfortran.dg/pr91552.f90 (working copy)
@@ -0,0 +1,10 @@
+! { dg-do run }
+! PR fortran/91552
+! Code contributed by Gerhard Steinmetz.
+program p
+ real :: y(3), z(4)
+ y = 2.0 * [real :: 1, [2], 3]
+ z = 2.0 * [real :: 1, [2, [4]], 3]
+ if (any(y /= [2., 4., 6.])) stop 1
+ if (any(z /= [2., 4., 8., 6.])) stop 2
+end