Thanks, as you point out all the test needs to do is verify that that a
variable with an AUTOMATIC attribute can be used in an EQUIVALENCE and
and that the items in the EQUIVALENCE are on the stack by using in a
recursive routine.
I've created a patch to replace the existing test cases and have sent it
to this e-mail thread https://gcc.gnu.org/ml/fortran/2019-09/msg00123.html
regards,
Mark
On 30/09/2019 11:24, Jakub Jelinek wrote:
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
--
https://www.codethink.co.uk/privacy.html