diff mbox series

PR fortran/91552 -- Walk array constructor to do type conversion

Message ID 20190831201544.GA14621@troutmask.apl.washington.edu
State New
Headers show
Series PR fortran/91552 -- Walk array constructor to do type conversion | expand

Commit Message

Steve Kargl Aug. 31, 2019, 8:15 p.m. UTC
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.

Comments

Paul Richard Thomas Sept. 1, 2019, 12:58 p.m. UTC | #1
Hi Steve,

OK to commit.

Thanks

Paul

On Sat, 31 Aug 2019 at 21:16, Steve Kargl
<sgk@troutmask.apl.washington.edu> wrote:
>
> 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
diff mbox series

Patch

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