Hello world,

the attached patch fixes the bug that Steve found; the patch itself
simply makes sure to copy a constructor instead of only the value
of the constructor when converting types.

Regressoin-tested. OK for trunk?

Maybe this is also a candidate for gcc-7, because of the silent
wrong-code issue.

Regards

        Thomas

2018-03-18  Thomas Koenig  <tkoe...@gcc.gnu.org>

        PR fortran/84931
        * simplify.c (gfc_convert_constant): Correctly handle iterators
        for type conversion.

2018-03-18  Thomas Koenig  <tkoe...@gcc.gnu.org>

        PR fortran/84931
        * gfortran.dg/array_constructor_52.f90: New test.
Index: simplify.c
===================================================================
--- simplify.c	(Revision 258501)
+++ simplify.c	(Arbeitskopie)
@@ -8016,26 +8016,32 @@ gfc_convert_constant (gfc_expr *e, bt type, int ki
 	{
 	  gfc_expr *tmp;
 	  if (c->iterator == NULL)
-	    tmp = f (c->expr, kind);
+	    {
+	      tmp = f (c->expr, kind);
+	      if (tmp == NULL)
+		{
+		  gfc_free_expr (result);
+		  return NULL;
+		}
+
+	      gfc_constructor_append_expr (&result->value.constructor,
+					   tmp, &c->where);
+	    }
 	  else
 	    {
+	      gfc_constructor *n;
 	      g = gfc_convert_constant (c->expr, type, kind);
-	      if (g == &gfc_bad_expr)
+	      if (g == NULL || g == &gfc_bad_expr)
 	        {
 		  gfc_free_expr (result);
 		  return g;
 		}
-	      tmp = g;
+	      n = gfc_constructor_get ();
+	      n->expr = g;
+	      n->iterator = gfc_copy_iterator (c->iterator);
+	      n->where = c->where;
+	      gfc_constructor_append (&result->value.constructor, n);
 	    }
-
-	  if (tmp == NULL)
-	    {
-	      gfc_free_expr (result);
-	      return NULL;
-	    }
-
-	  gfc_constructor_append_expr (&result->value.constructor,
-				       tmp, &c->where);
 	}
 
       break;
! { dg-do  run }
! PR 84931 - long array constructors with type conversion were not
! handled correctly.
program test
   implicit none
   integer, parameter :: n = 2**16
   real, dimension(n) :: y
   integer :: i
   y = (/ (1, i=1, n) /)
   if (y(2) /= 1) stop 1
end program test

Reply via email to