@@ -67,13 +67,29 @@ static RT_API_ATTRS Fortran::common::optional<bool> DefinedFormattedIo(
67
67
ioType, io.mutableModes ().inNamelist ? " NAMELIST" : " LISTDIRECTED" );
68
68
ioTypeLen = runtime::strlen (ioType);
69
69
}
70
+ // V_LIST= argument
70
71
StaticDescriptor<1 , true > vListStatDesc;
71
72
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
+ }
77
93
ExternalFileUnit *actualExternal{io.GetExternalFileUnit ()};
78
94
ExternalFileUnit *external{actualExternal};
79
95
if (!external) {
@@ -84,8 +100,8 @@ static RT_API_ATTRS Fortran::common::optional<bool> DefinedFormattedIo(
84
100
ChildIo &child{external->PushChildIo (io)};
85
101
// Child formatted I/O is nonadvancing by definition (F'2018 12.6.2.4).
86
102
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};
89
105
char ioMsg[100 ];
90
106
Fortran::common::optional<std::int64_t > startPos;
91
107
if (edit.descriptor == DataEdit::DefinedDerivedType &&
@@ -98,23 +114,45 @@ static RT_API_ATTRS Fortran::common::optional<bool> DefinedFormattedIo(
98
114
derived.binding ().OffsetElement <const typeInfo::Binding>()};
99
115
if (special.IsArgDescriptor (0 )) {
100
116
// "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)};
104
117
StaticDescriptor<1 , true , 10 /* ?*/ > elementStatDesc;
105
118
Descriptor &elementDesc{elementStatDesc.descriptor ()};
106
119
elementDesc.Establish (
107
120
derived, nullptr , 0 , nullptr , CFI_attribute_pointer);
108
121
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
+ }
111
138
} else {
112
139
// "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
+ }
118
156
}
119
157
handler.Forward (ioStat, ioMsg, sizeof ioMsg);
120
158
external->PopChildIo (child);
@@ -458,11 +496,16 @@ RT_API_ATTRS int DescriptorIoTicket<DIR>::Begin(WorkQueue &workQueue) {
458
496
? common::DefinedIo::ReadUnformatted
459
497
: common::DefinedIo::WriteUnformatted)}) {
460
498
if (definedIo->subroutine ) {
499
+ std::uint8_t isArgDescriptorSet{0 };
500
+ if (definedIo->flags & IsDtvArgPolymorphic) {
501
+ isArgDescriptorSet = 1 ;
502
+ }
461
503
typeInfo::SpecialBinding special{DIR == Direction::Input
462
504
? typeInfo::SpecialBinding::Which::ReadUnformatted
463
505
: typeInfo::SpecialBinding::Which::WriteUnformatted,
464
- definedIo->subroutine , definedIo->isDtvArgPolymorphic , false ,
465
- false };
506
+ definedIo->subroutine , isArgDescriptorSet,
507
+ /* IsTypeBound=*/ false ,
508
+ /* specialCaseFlag=*/ !!(definedIo->flags & DefinedIoInteger8)};
466
509
if (DefinedUnformattedIo (io_, instance_, *type, special)) {
467
510
anyIoTookPlace_ = true ;
468
511
return StatOk;
@@ -719,8 +762,11 @@ RT_API_ATTRS int DescriptorIoTicket<DIR>::Begin(WorkQueue &workQueue) {
719
762
nonTbpSpecial_.emplace (DIR == Direction::Input
720
763
? typeInfo::SpecialBinding::Which::ReadFormatted
721
764
: 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));
724
770
special_ = &*nonTbpSpecial_;
725
771
}
726
772
}
0 commit comments