Fortran: error recovery simplifying PACK with invalid arguments [PR106049]

Message ID trinity-496cd4b0-bce1-425b-9da2-2d81efd21e01-1657053102400@3c-app-gmx-bs53
State New
Headers
Series Fortran: error recovery simplifying PACK with invalid arguments [PR106049] |

Commit Message

Harald Anlauf July 5, 2022, 8:31 p.m. UTC
  Dear all,

poor error recovery while trying to simplify intrinsics with given
invalid arguments seems to be a recurrent theme in testcases submitted
by Gerhard.  In the present case, simplification of PACK() chokes on
the array argument being a bad decl.

The most general approach that came to my mind is to modify function
is_constant_array_expr: when the declared shape of the array indicates
a size greater than zero, but the constructor is missing or empty,
then something bad may have happened, and the array cannot be
considered constant.  We thus punt on simplification of something
that cannot be simplified.  With some luck, this might prevent issues
in similar cases elsewhere...

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

Thanks,
Harald
  

Comments

Harald Anlauf July 12, 2022, 6:23 p.m. UTC | #1
As there were no comments, committed as r13-1650.

Am 05.07.22 um 22:31 schrieb Harald Anlauf via Fortran:
> Dear all,
>
> poor error recovery while trying to simplify intrinsics with given
> invalid arguments seems to be a recurrent theme in testcases submitted
> by Gerhard.  In the present case, simplification of PACK() chokes on
> the array argument being a bad decl.
>
> The most general approach that came to my mind is to modify function
> is_constant_array_expr: when the declared shape of the array indicates
> a size greater than zero, but the constructor is missing or empty,
> then something bad may have happened, and the array cannot be
> considered constant.  We thus punt on simplification of something
> that cannot be simplified.  With some luck, this might prevent issues
> in similar cases elsewhere...
>
> Regtested on x86_64-pc-linux-gnu.  OK for mainline?
>
> Thanks,
> Harald
>
  

Patch

From b70a225cd9ac83cd182938bb8019f9138f85b222 Mon Sep 17 00:00:00 2001
From: Harald Anlauf <anlauf@gmx.de>
Date: Tue, 5 Jul 2022 22:20:05 +0200
Subject: [PATCH] Fortran: error recovery simplifying PACK with invalid
 arguments [PR106049]

gcc/fortran/ChangeLog:

	PR fortran/106049
	* simplify.cc (is_constant_array_expr): A non-zero-sized constant
	array shall have a non-empty constructor.  When the constructor is
	empty or missing, treat as non-constant.

gcc/testsuite/ChangeLog:

	PR fortran/106049
	* gfortran.dg/pack_simplify_1.f90: New test.
---
 gcc/fortran/simplify.cc                       | 12 ++++++++++++
 gcc/testsuite/gfortran.dg/pack_simplify_1.f90 | 15 +++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/pack_simplify_1.f90

diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index ab59fbca622..fb725994653 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -233,6 +233,18 @@  is_constant_array_expr (gfc_expr *e)
   if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
     return false;

+  /* A non-zero-sized constant array shall have a non-empty constructor.  */
+  if (e->rank > 0 && e->shape != NULL && e->value.constructor == NULL)
+    {
+      mpz_init_set_ui (size, 1);
+      for (int j = 0; j < e->rank; j++)
+	mpz_mul (size, size, e->shape[j]);
+      bool not_size0 = (mpz_cmp_si (size, 0) != 0);
+      mpz_clear (size);
+      if (not_size0)
+	return false;
+    }
+
   for (c = gfc_constructor_first (e->value.constructor);
        c; c = gfc_constructor_next (c))
     if (c->expr->expr_type != EXPR_CONSTANT
diff --git a/gcc/testsuite/gfortran.dg/pack_simplify_1.f90 b/gcc/testsuite/gfortran.dg/pack_simplify_1.f90
new file mode 100644
index 00000000000..06bc55a14f3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pack_simplify_1.f90
@@ -0,0 +1,15 @@ 
+! { dg-do compile }
+! PR fortran/106049 - ICE in gfc_simplify_pack
+! Contributed by G.Steinmetz
+
+program p
+  type t
+  end type
+  logical, parameter :: m(0) = [ logical :: ]
+  type(t), parameter :: a(0) = [ t :: ]
+  type(t), parameter :: b(1) = [ t()  ]
+  type(t), parameter :: c(1) = [ t :: ]        ! { dg-error "Different shape" }
+  type(t), parameter :: d(0) = pack(a, m)
+  type(t), parameter :: e(1) = pack(b, [.true.])
+  type(t), parameter :: f(1) = pack(c, [.true.])
+end
--
2.35.3