https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125458
--- Comment #11 from Steve Kargl <kargl at gcc dot gnu.org> ---
(In reply to Thomas Koenig from comment #9)
> I have found this to be deep regression country.
>
> One problem that I see is that the arith* functions are called both
> during matching and during resolution, and they should be doing
> somewhat different things upon encountering an error. I've toyed
> with the idea of putting in a global variable which states which
> phase we are currently in (matching, resolution, front-end optimization
> and translation) and handling errors differently based on that,
> but I don't have the time for that at the moment.
>
> Steve, maybe you have an idea?
Just spent an hour or 2 tracing through the parsing.
At some point, arith.cc(is_hard_arith_error) is called
and it it considered to be a *not hard error* so
gfortran accepts the resulting multiplication. This
occurs even if -frange-check is specified on the command
line.
(gdb) n
869 return check_result (rc, op1, result, resultp);
(gdb) p rc
$8 = ARITH_OVERFLOW
We see rc=ARITH_OVERFLOW and
(gdb) s
check_result (rc=ARITH_OVERFLOW, x=0x804413c40, r=0x804413e00,
rp=0x7fffffffdad8)
at ../../gcc/gcc/fortran/arith.cc:662
662 if (val == ARITH_UNDERFLOW)
(gdb)
669 if (val == ARITH_ASYMMETRIC)
(gdb)
675 if (is_hard_arith_error (val))
(gdb) s
is_hard_arith_error (code=ARITH_OVERFLOW) at ../../gcc/gcc/fortran/arith.cc:156
156 switch (code)
(gdb) s
check_result (rc=<optimized out>, x=<optimized out>, r=<optimized out>,
rp=<optimized out>) at ../../gcc/gcc/fortran/arith.cc:678
678 *rp = r;
this is where gfortran accepts the result of the multiplication.
(gdb) s
680 return val;
(gdb) p val
$9 = <optimized out>
(gdb) n
eval_intrinsic (op=op@entry=INTRINSIC_TIMES, eval=eval@entry=...,
op1=0x804413c40, op2=0x804413d20) at ../../gcc/gcc/fortran/arith.cc:1964
1964 if (rc == ARITH_INVALID_TYPE || rc == ARITH_NOT_REDUCED)
(gdb) p rc
$10 = ARITH_OVERFLOW
(gdb) call debug(result)
28958985279684 (INTEGER 4)
The finger points at Harald.
commit 93e1d4d24ed014387da97e2ce11556d68fe98e66
Author: Harald Anlauf <[email protected]>
AuthorDate: Tue Mar 5 21:54:26 2024 +0100
Commit: Harald Anlauf <[email protected]>
CommitDate: Wed Mar 6 17:55:36 2024 +0100
Fortran: error recovery while simplifying expressions [PR103707,PR106987]
When an exception is encountered during simplification of arithmetic
expressions, the result may depend on whether range-checking is active
(-frange-check) or not. However, the code path in the front-end should
stay the same for "soft" errors for which the exception is triggered by the
check, while "hard" errors should always terminate the simplification, so
that error recovery is independent of the flag. Separation of arithmetic
error codes into "hard" and "soft" errors shall be done consistently via
is_hard_arith_error().
If I force is_hard_arith_error() to return true, which rejects the
result, I get an ICE. :( This is likely a NULL dereference of a
freed expr->where.