https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125397
Bug ID: 125397
Summary: [16 Regression] -fcheck=bounds segfault on 2D array
slice through CLASS dummy argument
Product: gcc
Version: 16.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: federico.perini at gmail dot com
Target Milestone: ---
Created attachment 64511
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=64511&action=edit
Simple program reproducing the issue
Verify it on Compiler Explorer at: https://godbolt.org/z/xW7jqae6r
NOTE: gfortran(trunk) seems to handle this well but I can't find a similar
bugfix in gcc bugzilla. I am reporting this anyways because bound checking is a
staple of fortran programming, so it is probably a good idea to backport a fix
to 16.1 anyways.
Works on <=15.
- Condition for segfault: `-fcheck=bounds`
- Trigger for segfault: access n-D allocatable array slice, for example:
```
subroutine use_class(this)
class(t), intent(inout) :: this
print *, this%a(:,1) ! simple 2d alloc. array -> SEGFAULT if
`-fcheck=bounds`
end subroutine
```
Problem arouse on my side when MSYS2 upgraded to 16.1. I have to remove
`fcheck=bounds` everywhere as this issue affects many many classes.
I also tried -fdump-tree-original and I found:
struct outer * D.4809;
struct outer * D.4810;
...
D.4809 = this->_data; // assigns D.4809, but
unused
if (D.4810->a.dim[1].lbound > 1) ... // USES D.4810
if (D.4810->a.dim[1].ubound <= 0) ... // USES D.4810
D.4810 = this->_data; // finally assigns
D.4810
The bounds-check dereferences `D.4810` before it is initialized. The "garbage
bounds" reported at runtime are the contents of the uninitialized stack slot
where `D.4810` lives; `D.4809` is dead code, which suggests two temporaries
were swapped and the check was emitted before the assignment.
Thanks for looking into this,
Federico