This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
PR40011 -fwhole-file problems
- From: Paul Richard Thomas <paul dot richard dot thomas at gmail dot com>
- To: "fortran at gcc dot gnu dot org" <fortran at gcc dot gnu dot org>
- Date: Mon, 1 Jun 2009 21:03:02 +0200
- Subject: PR40011 -fwhole-file problems
Dear All,
I need some help, please!
The attachment to comment #28 of PR40011 is as far as I have got with
-fwhole-file improvements. Apart from fixing the problems listed in
the PR, the patch makes a first attempt to include module procedures.
In this patch, -fwhole-file is kludged up to be the default, to permit
regtesting.
There are a total of xxx FAILS, of which a good proportion are
anticipated real errors or legacy noise. Ther are some other
ICEs/errors that I know how to fix. There is however, one class that
I do not even know how to diagnose, let alone fix.
gfortran.dg/default_initialization_3.f90 fails at runtime at -O2. I
have reduced it to expose the problem:
! { dg-do run }
! Test the fix for PR34438, in which default initializers
! forced the derived type to be static; ie. initialized once
! during the lifetime of the programme. Instead, they should
! be initialized each time they come into scope.
!
module demo
type myint
integer :: bar = 42
end type myint
end module demo
! ...who came up with this one too.
subroutine func (ivalue, retval1, retval2)
use demo
integer, intent(in) :: ivalue
type(myint) :: foo1
type(myint) :: foo2 = myint (77)
type(myint) :: retval1
type(myint) :: retval2
retval1 = foo1
retval2 = foo2
foo1%bar = 999
foo2%bar = 999
end subroutine func
subroutine other
use demo
interface
subroutine func(ivalue, rv1, rv2)
use demo
integer, intent(in) :: ivalue
type(myint) :: foo, rv1, rv2
end subroutine func
end interface
type(myint) :: val1, val2
call func (1, val1, val2)
if ((val1%bar .ne. 42_4) .or. (val2%bar .ne. 77_4)) call abort ()
call func (2, val1, val2)
if ((val1%bar .ne. 42) .or. (val2%bar .ne. 999)) call abort ()
end subroutine other
! Run both tests.
call other
end
! { dg-final { cleanup-modules "demo M1" } }
at -O1, -fdump-tree-optiized gives:
;; Function func (func_)
func (integer(kind=4) & ivalue, struct myint & retval1, struct myint & retval2)
{
static struct myint foo2 = {.bar=77};
<bb 2>:
retval1_1(D)->bar = 42;
*retval2_2(D) = foo2;
foo2.bar = 999;
return;
}
;; Function other (other_)
other ()
{
struct myint val2;
struct myint val1;
integer(kind=4) D.1556;
integer(kind=4) D.1554;
<bb 2>:
val1.bar = 42;
val2.bar = 42;
func (&C.1547, &val1, &val2);
D.1554_1 = val1.bar;
if (D.1554_1 != 42)
goto <bb 4>;
else
goto <bb 3>;
<bb 3>:
D.1556_2 = val2.bar;
if (D.1556_2 != 77)
goto <bb 4>;
else
goto <bb 5>;
<bb 4>:
_gfortran_abort ();
<bb 5>:
func (&C.1549, &val1, &val2);
D.1554_3 = val1.bar;
if (D.1554_3 != 42)
goto <bb 7>;
else
goto <bb 6>;
<bb 6>:
D.1556_4 = val2.bar;
if (D.1556_4 != 999)
goto <bb 7>;
else
goto <bb 8>;
<bb 7>:
_gfortran_abort ();
<bb 8>:
return;
}
;; Function MAIN__ (MAIN__)
MAIN__ ()
{
static integer(kind=4) options.3[8] = {68, 255, 0, 0, 0, 1, 0, 1};
<bb 2>:
_gfortran_set_options (8, &options.3);
other ();
return;
}
Which looks fine. At -O2, however, we get:
func (integer(kind=4) & ivalue, struct myint & retval1, struct myint & retval2)
{
static struct myint foo2 = {.bar=77};
<bb 2>:
retval1_1(D)->bar = 42;
*retval2_2(D) = foo2;
foo2.bar = 999;
return;
}
;; Function other (other_)
other ()
{
static struct myint foo2 = {.bar=77};
static struct myint foo2 = {.bar=77};
static struct myint foo2 = {.bar=77};
struct myint & retval1;
struct myint & retval2;
struct myint val2;
struct myint val1;
<bb 2>:
retval1_12 = (struct myint &) &val1;
retval2_13 = (struct myint &) &val2;
retval1_12->bar = 42;
*retval2_13 = foo2;
foo2.bar = 999;
_gfortran_abort ();
}
Invalid sum of incoming frequencies 0, should be 9984
;; Function MAIN__ (MAIN__)
MAIN__ ()
{
static integer(kind=4) options.3[8] = {68, 255, 0, 0, 0, 1, 0, 1};
<bb 2>:
_gfortran_set_options (8, &options.3);
other (); [tail call]
return;
}
It looks to me as if the inlining gets completely messed up and that
abort () is called unconditionally. Containing 'func' within 'other'
runs without aborting but the code is still wrong.
Any ideas?
Paul