This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]