On Sat, Sep 28, 2019 at 10:33:26PM +0200, Andreas Schwab wrote: > On Aug 14 2019, Mark Eggleston <mark.eggles...@codethink.co.uk> wrote: > > > * gfortran.dg/auto_in_equiv_3.f90: New test. > > This test fails everywhere.
Yes, and _2 on i686-linux at -O0. To me both testcases are undefined behavior. E.g. the first one has: subroutine suba(option) integer, intent(in) :: option integer, automatic :: a integer :: b integer :: c equivalence (a, b) if (option.eq.0) then ! initialise a and c a = 9 c = 99 if (a.ne.b) stop 1 if (loc(a).ne.loc(b)) stop 2 else ! a should've been overwritten if (a.eq.9) stop 3 end if end subroutine suba My understanding is that because a is explicitly automatic and b is automatic too (implicitly), the whole equivalence is automatic, so if you call this subroutine with non-zero option, you read an uninitialized variable and compare it to 9. That can result in anything, .false., .true., disk formatting, you can't rely on some other routine laying out its automatic variable at exactly the same spot and overwriting the memory in there, not to mention that the compiler can easily spot the uninitialized use too. Similarly in the second test, returning address of an automatic variable from a function is already something e.g. the C/C++ FEs warn about, because you really can't do anything useful with that address, it can't be dereferenced, or even the comparisons to addresses of other automatic variables that left their scope is wrong. IMHO if you want to check if a variable is SAVEd or AUTOMATIC, you want to recurse, either directly or indirectly, pass the address of the variable in the outer subroutine down to the inner one and compare there, SAVEd variables need to have the same address, while AUTOMATIC variables where both the outer and inner variable is at that point still in the scope need to have the addresses different. Though, in order to have in Fortran a recursively callable subroutine, one needs to use RECURSIVE. So, IMHO we want 4 testcases out of these 2, two dg-do compile only which will verify the tests compile when mixing automatic with no explicit save/automatic in equivalence and will -fdump-tree-gimple and scan the gimple dump to verify there is equiv.\[0-9]* variable which is not static, and then two runtime testcases like (one with just -fdec-static, one with also -fno-automatic, though guess it doesn't matter that much, as recursive already implies that it is automatic). program test integer :: dummy integer, parameter :: address = kind(loc(dummy)) integer(address) :: addr addr = 0 call sub (0, addr) contains recursive subroutine sub (option, addr) integer, intent(in) :: option integer(address), intent(in) :: addr integer, automatic :: a integer :: b integer(address) :: c equivalence (a, b) if (option.eq.0) then a = 9 if (a.ne.b) stop 1 if (loc(a).ne.loc(b)) stop 2 c = loc(a) call sub (1, c) if (a.ne.9) stop 3 else a = 10 if (a.ne.b) stop 4 if (loc(a).ne.loc(b)) stop 5 if (addr.eq.loc(a)) stop 6 end if end subroutine sub end program test Jakub