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]

[Patch, fortran] [0/5] PR 45586: restrict vs. non-restrict type compatibility hell


Hello, 
here come several patches to fix the infamous PR 45586.  The main issue is
the middle-end expecting variant types to share the fields, thus one field
cannot be restrict qualified in one type, and not restrict qualified in one
of its variants.
The fix, as per Richi's suggestion, makes the types not be variants of each
other, but this raises type compatibility problems, as fold_convert triggers an
assertion if the types are not variants of the same base type.
The fix for that (suggested by Richi again) wraps the expression in a
VIEW_CONVERT_EXPR.
The above is not enough to make LTO happy.  There are problems with structure
constructors, where we use the restricted type, but the variable to assign to
is a target, thus has a non-restrict type.  The fix for that propagates the
information that we don't want restrict qualification from gfc_trans_assignment
down to gfc_conv_structure.  The same applies to array constructors.

The patch is split as follows:
[1/5]: Add the VIEW_CONVERT_EXPR wrapping.
[2/5]: Make target vs. non-target variant types distinct.
[3/5]: Use the target information to assign from structure constructors.
[4/5]: Use the target information to assign from array constructors.
[5/5]: Use the target information to assign a scalar structure to an array.

More details in the follow-up mails.


Regression tested on amd64-linux. OK for trunk?

Mikael

Attachment: pr45586-test.CL
Description: Text document

! { dg-do compile }
! { dg-options "-fdump-tree-original" }
!
! PR fortran/45586
! Test restricted vs. non-restricted (or target vs. non-target) type
! compatibility in assignments

  type :: t
    integer :: i
    integer, allocatable :: a(:)
    real :: r
  end type t

  type(t), target :: x, xx(1)
  type(t)         :: y, yy(1)

  x = t( 1, null(), -1.0)
  y = t(-1, null(),  1.0)
  x = y                        ! VIEW_CONVERT_EXPR
  y = x                        ! VIEW_CONVERT_EXPR
  x = t( 1, (/3/), -1.0)
  y = t(-1, (/4/),  1.0)
  x = func()                   ! VIEW_CONVERT_EXPR
  y = func()
  xx = x
  yy = y
  xx = t(1,  null(), -1.0)
  yy = t(-1, null(), 1.0)
  xx = y                        ! VIEW_CONVERT_EXPR
  yy = x                        ! VIEW_CONVERT_EXPR
  xx = yy                       ! VIEW_CONVERT_EXPR
  yy = xx                       ! VIEW_CONVERT_EXPR
  xx = t( 1, (/3/), -1.0)
  yy = t(-1, (/4/),  1.0)
  xx = (/x/)
  yy = (/y/)
  xx = (/t( 1, null(), -1.0)/)
  yy = (/t(-1, null(),  1.0)/)
  xx = (/y/)                    ! VIEW_CONVERT_EXPR
  yy = (/x/)                    ! VIEW_CONVERT_EXPR
  xx = (/yy/)                   ! VIEW_CONVERT_EXPR
  yy = (/xx/)                   ! VIEW_CONVERT_EXPR
  xx = (/t( 1, (/3/), -1.0)/)
  yy = (/t(-1, (/4/),  1.0)/)
  xx = func()                   ! VIEW_CONVERT_EXPR
  yy = func()
  xx = (/func()/)               ! VIEW_CONVERT_EXPR
  yy = (/func()/)

 contains
  
  function func() result(res)
    type(t) :: res
    res = t(2, (/5/), -2.0)
  end function func
end

! { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 13 "original" } }
! { dg-final { cleanup-tree-dump "original" } }

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