Dear Fortranners, I think I have solved the remaining issue in PR 102458 that prevented the simplification of an expression involving a static initialization and the evaluation of the SIZE of an automatic array which has provable constant size. My previous related query to the ML has thus become obsolete.
My solution is to attempt the resolution of the array specification within simplify_size so that the simplification actually works. Regtested on x86_64-pc-linux-gnu. OK for mainline and same branches as the patch for part1? Thanks, Harald
Fortran: resolve expressions during SIZE simplification gcc/fortran/ChangeLog: PR fortran/102458 * simplify.c (simplify_size): Resolve expressions used in array specifications so that SIZE can be simplified. gcc/testsuite/ChangeLog: PR fortran/102458 * gfortran.dg/pr102458b.f90: New test. diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index b46cbfa90ab..f40e4930b58 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -7471,6 +7471,7 @@ simplify_size (gfc_expr *array, gfc_expr *dim, int k) mpz_t size; gfc_expr *return_value; int d; + gfc_ref *ref; /* For unary operations, the size of the result is given by the size of the operand. For binary ones, it's the size of the first operand @@ -7527,6 +7528,10 @@ simplify_size (gfc_expr *array, gfc_expr *dim, int k) return simplified; } + for (ref = array->ref; ref; ref = ref->next) + if (ref->type == REF_ARRAY && ref->u.ar.as) + gfc_resolve_array_spec (ref->u.ar.as, 0); + if (dim == NULL) { if (!gfc_array_size (array, &size)) diff --git a/gcc/testsuite/gfortran.dg/pr102458b.f90 b/gcc/testsuite/gfortran.dg/pr102458b.f90 new file mode 100644 index 00000000000..3e1026e635a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr102458b.f90 @@ -0,0 +1,21 @@ +! { dg-do compile } +! { dg-options "-fdump-tree-original" } +! { dg-final { scan-tree-dump-times "_gfortran_stop_numeric" 0 "original" } } +! PR fortran/102458 + +subroutine s4 + integer, parameter :: n = 4 + integer :: w(transfer(n, n)) = 1 + integer :: x(transfer(n, n)) + integer :: y(2*int(n) - n) + type t + integer :: z(int(n)) + end type t + type(t) :: tt, uu(3) + integer, parameter :: i = size (w) + integer, parameter :: k = size (x) + integer, parameter :: m = size (y) + integer, parameter :: j = size (tt% z) + integer, parameter :: l = size (uu(2)% z) + if (i /= n .or. k /= n .or. m /= n .or. j /= n .or. l /= n) stop 1 +end