Hi!
do_subscript contains
do_sym = dl->ext.iterator->var->symtree->n.sym;
if (do_sym->ts.type != BT_INTEGER)
continue;
check to ignore loops with non-integral iterator. But r15-11154
PR94978 change has added inner_loop_may_be_skipped function and that
happily accesses inner loop iterator's step, start and end if EXPR_CONSTANT
with mpz_init_set (..., ...value.integer);
Now, given the layout of mpfr_t (usually long, int, long, pointer)
and mpz_t (usually int, int, pointer), this sometimes just produces silently
garbage (e.g. on 64-bit little-endian, where the second int in mpz_t is
the most significant 32-bits of _mpfr_prec and so usually 0 and so _mp_size
is 0 and nothing is dereferenced:
p loop->ext.iterator->step.value.real
$1 = {{_mpfr_prec = 24, _mpfr_sign = 1, _mpfr_exp = 1, _mpfr_d = 0x4eac658}}
p loop->ext.iterator->step.value.integer
$2 = {{_mp_alloc = 24, _mp_size = 0, _mp_d = 0x1}}
or it ICEs somewhere in gmp (on 32-bit little-endian, e.g. i686, or
big-endian, e.g. s390x), because _mp_size is in that case _mpfr_sign but
_mp_d is _mpfr_exp (32-bit little-endian), or _mp_size is least significant
part of _mpfr_prec, in both cases non-zero, but _mp_d is not a usable
pointer in either case.
The following patch fixes that by punting for inner loops with non-integral
iterator.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and
affected release branches (I think 14+, the patch has been backported)?
2026-07-20 Jakub Jelinek <[email protected]>
PR fortran/126303
* frontend-passes.cc (inner_loop_may_be_skipped): If inner loop iterator
is not integral, return true.
* gfortran.dg/pr126303.f: New test.
--- gcc/fortran/frontend-passes.cc.jj 2026-06-01 23:00:32.170970754 +0200
+++ gcc/fortran/frontend-passes.cc 2026-07-17 16:27:33.510790350 +0200
@@ -2778,6 +2778,9 @@ inner_loop_may_be_skipped (int loop_inde
if (loop == NULL || loop->ext.iterator == NULL ||
loop->ext.iterator->var == NULL)
return true;
+ if (loop->ext.iterator->var->symtree->n.sym->ts.type != BT_INTEGER)
+ return true;
+
if (!evaluate_loop_bound (loop->ext.iterator->step, outer_sym,
outer_val, do_step))
return true;
--- gcc/testsuite/gfortran.dg/pr126303.f.jj 2026-07-17 16:24:51.390803180
+0200
+++ gcc/testsuite/gfortran.dg/pr126303.f 2026-07-17 16:24:33.510025181
+0200
@@ -0,0 +1,9 @@
+! PR fortran/126303
+! { dg-do compile }
+! { dg-options "-std=legacy" }
+ COMMON FOO(8)
+ DO 10 M=1,8
+ DO 10 T=0D0,1D0
+ FOO(M)=1
+ 10 CONTINUE
+ END
Jakub