@@ -67,13 +67,29 @@ static RT_API_ATTRS Fortran::common::optional<bool> DefinedFormattedIo(
6767 ioType, io.mutableModes ().inNamelist ? " NAMELIST" : " LISTDIRECTED" );
6868 ioTypeLen = runtime::strlen (ioType);
6969 }
70+ // V_LIST= argument
7071 StaticDescriptor<1 , true > vListStatDesc;
7172 Descriptor &vListDesc{vListStatDesc.descriptor ()};
72- vListDesc.Establish (TypeCategory::Integer, sizeof (int ), nullptr , 1 );
73- vListDesc.set_base_addr (edit.vList );
74- vListDesc.GetDimension (0 ).SetBounds (1 , edit.vListEntries );
75- vListDesc.GetDimension (0 ).SetByteStride (
76- static_cast <SubscriptValue>(sizeof (int )));
73+ bool integer8{special.specialCaseFlag ()};
74+ std::int64_t vList64[edit.maxVListEntries ];
75+ if (integer8) {
76+ // Convert v_list values to INTEGER(8)
77+ for (int j{0 }; j < edit.vListEntries ; ++j) {
78+ vList64[j] = edit.vList [j];
79+ }
80+ vListDesc.Establish (
81+ TypeCategory::Integer, sizeof (std::int64_t ), nullptr , 1 );
82+ vListDesc.set_base_addr (vList64);
83+ vListDesc.GetDimension (0 ).SetBounds (1 , edit.vListEntries );
84+ vListDesc.GetDimension (0 ).SetByteStride (
85+ static_cast <SubscriptValue>(sizeof (std::int64_t )));
86+ } else {
87+ vListDesc.Establish (TypeCategory::Integer, sizeof (int ), nullptr , 1 );
88+ vListDesc.set_base_addr (edit.vList );
89+ vListDesc.GetDimension (0 ).SetBounds (1 , edit.vListEntries );
90+ vListDesc.GetDimension (0 ).SetByteStride (
91+ static_cast <SubscriptValue>(sizeof (int )));
92+ }
7793 ExternalFileUnit *actualExternal{io.GetExternalFileUnit ()};
7894 ExternalFileUnit *external{actualExternal};
7995 if (!external) {
@@ -84,8 +100,8 @@ static RT_API_ATTRS Fortran::common::optional<bool> DefinedFormattedIo(
84100 ChildIo &child{external->PushChildIo (io)};
85101 // Child formatted I/O is nonadvancing by definition (F'2018 12.6.2.4).
86102 auto restorer{common::ScopedSet (io.mutableModes ().nonAdvancing , true )};
87- int unit{external->unitNumber ()};
88- int ioStat{IostatOk};
103+ std:: int32_t unit{external->unitNumber ()};
104+ std:: int32_t ioStat{IostatOk};
89105 char ioMsg[100 ];
90106 Fortran::common::optional<std::int64_t > startPos;
91107 if (edit.descriptor == DataEdit::DefinedDerivedType &&
@@ -98,23 +114,45 @@ static RT_API_ATTRS Fortran::common::optional<bool> DefinedFormattedIo(
98114 derived.binding ().OffsetElement <const typeInfo::Binding>()};
99115 if (special.IsArgDescriptor (0 )) {
100116 // "dtv" argument is "class(t)", pass a descriptor
101- auto *p{special.GetProc <void (*)(const Descriptor &, int &, char *,
102- const Descriptor &, int &, char *, std::size_t , std::size_t )>(
103- bindings)};
104117 StaticDescriptor<1 , true , 10 /* ?*/ > elementStatDesc;
105118 Descriptor &elementDesc{elementStatDesc.descriptor ()};
106119 elementDesc.Establish (
107120 derived, nullptr , 0 , nullptr , CFI_attribute_pointer);
108121 elementDesc.set_base_addr (descriptor.Element <char >(subscripts));
109- p (elementDesc, unit, ioType, vListDesc, ioStat, ioMsg, ioTypeLen,
110- sizeof ioMsg);
122+ if (integer8) { // 64-bit UNIT=/IOSTAT=
123+ std::int64_t unit64{unit};
124+ std::int64_t ioStat64{ioStat};
125+ auto *p{special.GetProc <void (*)(const Descriptor &, std::int64_t &,
126+ char *, const Descriptor &, std::int64_t &, char *, std::size_t ,
127+ std::size_t )>(bindings)};
128+ p (elementDesc, unit64, ioType, vListDesc, ioStat64, ioMsg, ioTypeLen,
129+ sizeof ioMsg);
130+ ioStat = ioStat64;
131+ } else { // 32-bit UNIT=/IOSTAT=
132+ auto *p{special.GetProc <void (*)(const Descriptor &, std::int32_t &,
133+ char *, const Descriptor &, std::int32_t &, char *, std::size_t ,
134+ std::size_t )>(bindings)};
135+ p (elementDesc, unit, ioType, vListDesc, ioStat, ioMsg, ioTypeLen,
136+ sizeof ioMsg);
137+ }
111138 } else {
112139 // "dtv" argument is "type(t)", pass a raw pointer
113- auto *p{special.GetProc <void (*)(const void *, int &, char *,
114- const Descriptor &, int &, char *, std::size_t , std::size_t )>(
115- bindings)};
116- p (descriptor.Element <char >(subscripts), unit, ioType, vListDesc, ioStat,
117- ioMsg, ioTypeLen, sizeof ioMsg);
140+ if (integer8) { // 64-bit UNIT= and IOSTAT=
141+ std::int64_t unit64{unit};
142+ std::int64_t ioStat64{ioStat};
143+ auto *p{special.GetProc <void (*)(const void *, std::int64_t &, char *,
144+ const Descriptor &, std::int64_t &, char *, std::size_t ,
145+ std::size_t )>(bindings)};
146+ p (descriptor.Element <char >(subscripts), unit64, ioType, vListDesc,
147+ ioStat64, ioMsg, ioTypeLen, sizeof ioMsg);
148+ ioStat = ioStat64;
149+ } else { // 32-bit UNIT= and IOSTAT=
150+ auto *p{special.GetProc <void (*)(const void *, std::int32_t &, char *,
151+ const Descriptor &, std::int32_t &, char *, std::size_t ,
152+ std::size_t )>(bindings)};
153+ p (descriptor.Element <char >(subscripts), unit, ioType, vListDesc, ioStat,
154+ ioMsg, ioTypeLen, sizeof ioMsg);
155+ }
118156 }
119157 handler.Forward (ioStat, ioMsg, sizeof ioMsg);
120158 external->PopChildIo (child);
@@ -458,11 +496,16 @@ RT_API_ATTRS int DescriptorIoTicket<DIR>::Begin(WorkQueue &workQueue) {
458496 ? common::DefinedIo::ReadUnformatted
459497 : common::DefinedIo::WriteUnformatted)}) {
460498 if (definedIo->subroutine ) {
499+ std::uint8_t isArgDescriptorSet{0 };
500+ if (definedIo->flags & IsDtvArgPolymorphic) {
501+ isArgDescriptorSet = 1 ;
502+ }
461503 typeInfo::SpecialBinding special{DIR == Direction::Input
462504 ? typeInfo::SpecialBinding::Which::ReadUnformatted
463505 : typeInfo::SpecialBinding::Which::WriteUnformatted,
464- definedIo->subroutine , definedIo->isDtvArgPolymorphic , false ,
465- false };
506+ definedIo->subroutine , isArgDescriptorSet,
507+ /* IsTypeBound=*/ false ,
508+ /* specialCaseFlag=*/ !!(definedIo->flags & DefinedIoInteger8)};
466509 if (DefinedUnformattedIo (io_, instance_, *type, special)) {
467510 anyIoTookPlace_ = true ;
468511 return StatOk;
@@ -719,8 +762,11 @@ RT_API_ATTRS int DescriptorIoTicket<DIR>::Begin(WorkQueue &workQueue) {
719762 nonTbpSpecial_.emplace (DIR == Direction::Input
720763 ? typeInfo::SpecialBinding::Which::ReadFormatted
721764 : typeInfo::SpecialBinding::Which::WriteFormatted,
722- definedIo->subroutine , definedIo->isDtvArgPolymorphic , false ,
723- false );
765+ definedIo->subroutine ,
766+ /* isArgDescriptorSet=*/
767+ (definedIo->flags & IsDtvArgPolymorphic) ? 1 : 0 ,
768+ /* isTypeBound=*/ false ,
769+ /* specialCaseFlag=*/ !!(definedIo->flags & DefinedIoInteger8));
724770 special_ = &*nonTbpSpecial_;
725771 }
726772 }
0 commit comments