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
From b70a225cd9ac83cd182938bb8019f9138f85b222 Mon Sep 17 00:00:00 2001 From: Harald Anlauf <anl...@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