Skip to content

Conversation

@klausler
Copy link
Contributor

@klausler klausler commented Nov 6, 2025

List-directed child input is allowed to advance to new records in some circumstances, and list-directed output should be as well so that e.g. NAMELIST output via a defined WRITE(FORMATTED) generic doesn't get truncated by FORT_FMT_RECL.

Fixes #166804.

List-directed child input is allowed to advance to new records
in some circumstances, and list-directed output should be as well
so that e.g. NAMELIST output via a defined WRITE(FORMATTED) generic
doesn't get truncated by FORT_FMT_RECL.

Fixes llvm#166804.
@klausler klausler merged commit 1baf7db into llvm:main Nov 7, 2025
11 checks passed
@klausler klausler deleted the bug166804 branch November 7, 2025 16:42
@DanielCChen
Copy link
Contributor

DanielCChen commented Nov 7, 2025

The reduced test case is fixed as well as the corresponding portion of the full test case.
Thanks!

However, the full test case still fails probably due to a different variation.
I will open a new issue to track it.

Update: The full test case is actually passing. The failure I saw was due to an IBM extension that allows "true" dynamic type in array constructor.

@klausler
Copy link
Contributor Author

klausler commented Nov 7, 2025

Please attach full test cases to bugs so that I don't have to fix things twice.

vinay-deshmukh pushed a commit to vinay-deshmukh/llvm-project that referenced this pull request Nov 8, 2025
…vm#166847)

List-directed child input is allowed to advance to new records in some
circumstances, and list-directed output should be as well so that e.g.
NAMELIST output via a defined WRITE(FORMATTED) generic doesn't get
truncated by FORT_FMT_RECL.

Fixes llvm#166804.
@DanielCChen
Copy link
Contributor

Please attach full test cases to bugs so that I don't have to fix things twice.

The test case is testing the dynamic type of the AC value rather than it's declare type as the standard says (Its dynamic type is its declared type). It is an extension to the standard. Would it be a candidate extension for Flang as well?

@klausler
Copy link
Contributor Author

Please attach full test cases to bugs so that I don't have to fix things twice.

The test case is testing the dynamic type of the AC value rather than it's declare type as the standard says (Its dynamic type is its declared type). It is an extension to the standard. Would it be a candidate extension for Flang as well?

I don't understand this, but if you show me a test case in point out the behavior that you want, I'll be happy to consider an extension.

@DanielCChen
Copy link
Contributor

module m

   type :: data
      integer :: i, j
   end type

   type :: base
      type(data) :: d1
   end type

   type, extends(base) :: child
      type(data) :: d2
   end type

   interface write(formatted)
      subroutine writeformatted(dtv, unit, iotype, v_list, iostat, iomsg )
         import base
         class(base), intent(in) :: dtv
         integer,  intent(in) :: unit
         character(*), intent(in) :: iotype
         integer, intent(in)     :: v_list(:)
         integer,  intent(out) :: iostat
         character(*),  intent(inout) :: iomsg
      end subroutine
  end interface

   class(base), pointer :: b2(:,:)
   namelist /nml1/ b2

end module

program array001b
   use m

   integer :: stat
   character(200) :: msg = ''
   class(base), allocatable :: b1(:)

   allocate(b1(2), source = (/ child(data(1001,1002), data(1003,1004)), child(data(1005,1006), data(1007,1008)) /))
   allocate(b2(2,2), source = reshape ( source = (/ b1, b1 /) , shape = (/ 2, 2 /) )  )

   write (6,NML=nml1, iostat=stat, iomsg=msg)
   if ( stat /=  0 ) ERROR STOP(1_4)

end program

subroutine writeformatted (dtv, unit, iotype, v_list, iostat, iomsg)
   use m, only: base, child

   class(base), intent(in) :: dtv
   integer, intent(in) :: unit
   character(*), intent(in) :: iotype
   integer, intent(in)     :: v_list(:)
   integer, intent(out) :: iostat
   character(*), intent(inout) :: iomsg

   if ( iotype /= "NAMELIST" ) ERROR STOP(3_4)
   if ( size(v_list, 1) /= 0 ) ERROR STOP(4_4)

   select type ( m => dtv )
      class is (base)
         write (unit, *, iostat=iostat )      m%d1
      type is (child)
         write (unit, *, iostat=iostat )      m%d1
         write (unit, *, iostat=iostat )      m%d2
   end select

   iomsg = 'dtiowrite'

end subroutine

For this code, XLF has an compile time option to use the dynamic type of b1 when it is used as the source= to allocate b2. The output then is

> a.out
 &NML1 B2=1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008/

instead of

> a.out
&NML1 B2=1001, 1002, 1005, 1006, 1001, 1002, 1005, 1006/

This is not related to DTIO rather an extension to the array constructor.

@klausler
Copy link
Contributor Author

If the extension only pertains to ALLOCATE(..., SOURCE=), could you write a shorter demonstration case?

@DanielCChen
Copy link
Contributor

Sure.

   type :: data
      integer :: i, j
   end type

   type :: base
      type(data) :: d1
   end type

   type, extends(base) :: child
      type(data) :: d2
   end type

   class(base), pointer :: b2(:,:)
   class(base), allocatable :: b1(:)

   allocate(b1(2), source = (/ child(data(1001,1002), data(1003,1004)), child(data(1005,1006), data(1007,1008)) /))
   allocate(b2(2,2), source = reshape ( source = (/ b1, b1 /) , shape = (/ 2, 2 /) )  )
   select type(b2)
     type is (child)
       print*, "child"
     class is (base)
       print*, "base"
   end select

end program

With the extension, XLF prints

> a.out
 child

Without , it prints

> a.out
base

@klausler
Copy link
Contributor Author

So the extension is to interpret an array constructor with no explicit type-spec as having the dynamic type of its elements, not their common declared type, when the elements are polymorphic? And this is independent of the context -- it is not peculiar to SOURCE= specifiers in ALLOCATE statements?

@DanielCChen
Copy link
Contributor

Right. It could be at other places where the array constructor is used. (Not limited to the SOURCE=).

@klausler
Copy link
Contributor Author

Right. It could be at other places where the array constructor is used. (Not limited to the SOURCE=).

Thanks for the confirmation. In short, you want polymorphic array constructors that would work like anonymous polymorphic allocatables. Does any Fortran compiler besides XLF support this feature?

@DanielCChen
Copy link
Contributor

Not really. Even for XLF, it is not the default behavior. We have some test cases that are testing this non-default option and behavior.
As for this PR, I have fixed the relative test cases to use the default behavior so they are not blocked (excluded) because of the non-default behavior.
I am not pushing for adding the extension to Flang. This discussion is more like to clarify what I meant when I originally said the "full test case still fails."

@klausler
Copy link
Contributor Author

Ok, thanks. I think I'll leave this extension unimplemented until/unless there's a request for it from an application or library developer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[flang] DTIO failure with parent component

3 participants