Fortran:Fix simplification of constructors with implied-do [PR98458]
authorPaul Thomas <pault@gcc.gnu.org>
Fri, 8 Jan 2021 10:11:00 +0000 (10:11 +0000)
committerPaul Thomas <pault@gcc.gnu.org>
Fri, 8 Jan 2021 10:11:00 +0000 (10:11 +0000)
2021-01-08  Paul Thomas  <pault@gcc.gnu.org>

gcc/fortran
PR fortran/98458
* simplify.c (is_constant_array_expr): If an array constructor
expression has elements other than constants or structures, try
fixing the expression with gfc_reduce_init_expr. Also, if shape
is NULL, obtain the array size and set it.

gcc/testsuite/
PR fortran/98458
* gfortran.dg/implied_do_3.f90 : New test.

gcc/fortran/simplify.c
gcc/testsuite/gfortran.dg/implied_do_3.f90 [new file with mode: 0644]

index dac48a819ff49f826ec71022075736054630891c..23317a2e2d9a4b27800aeacb48757dbff61c9248 100644 (file)
@@ -220,6 +220,8 @@ static bool
 is_constant_array_expr (gfc_expr *e)
 {
   gfc_constructor *c;
+  bool array_OK = true;
+  mpz_t size;
 
   if (e == NULL)
     return true;
@@ -231,13 +233,43 @@ is_constant_array_expr (gfc_expr *e)
   if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
     return false;
 
+  for (c = gfc_constructor_first (e->value.constructor);
+       c; c = gfc_constructor_next (c))
+    if (c->expr->expr_type != EXPR_CONSTANT
+         && c->expr->expr_type != EXPR_STRUCTURE)
+      {
+       array_OK = false;
+       break;
+      }
+
+  /* Check and expand the constructor.  */
+  if (!array_OK && gfc_init_expr_flag && e->rank == 1)
+    {
+      array_OK = gfc_reduce_init_expr (e);
+      /* gfc_reduce_init_expr resets the flag.  */
+      gfc_init_expr_flag = true;
+    }
+  else
+    return array_OK;
+
+  /* Recheck to make sure that any EXPR_ARRAYs have gone.  */
   for (c = gfc_constructor_first (e->value.constructor);
        c; c = gfc_constructor_next (c))
     if (c->expr->expr_type != EXPR_CONSTANT
          && c->expr->expr_type != EXPR_STRUCTURE)
       return false;
 
-  return true;
+  /* Make sure that the array has a valid shape.  */
+  if (e->shape == NULL && e->rank == 1)
+    {
+      if (!gfc_array_size(e, &size))
+       return false;
+      e->shape = gfc_get_shape (1);
+      mpz_init_set (e->shape[0], size);
+      mpz_clear (size);
+    }
+
+  return array_OK;
 }
 
 /* Test for a size zero array.  */
diff --git a/gcc/testsuite/gfortran.dg/implied_do_3.f90 b/gcc/testsuite/gfortran.dg/implied_do_3.f90
new file mode 100644 (file)
index 0000000..8206332
--- /dev/null
@@ -0,0 +1,14 @@
+! { dg-do compile }
+!
+! Test the fix for PR98458 in which array expressions within the implied-do
+! array constructor caused an ICE in trans-array.c(gfc_conv_array_initializer).
+!
+! Contributed by Xiao Liu  <xiao.liu@compiler-dev.com>
+!
+program test
+  implicit none
+  integer :: i
+  integer, parameter :: t(6) = [1,2,3,4,5,6]
+  integer, parameter :: tmp(3,2) = reshape([(t(i:i+1),i=1,3)],[3,2])
+  print *, tmp  ! Used to ICE
+end