This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]