Skip to content

Commit aec90f2

Browse files
authored
[flang][runtime] Fix child input bugs under NAMELIST (#151571)
When NAMELIST input takes place on a derived type, we need to preserve the type in the descriptor that is created for storage sequence association. Further, the fact that any child list input in within the context of a NAMELIST must be inherited so that input fields don't try to consume later "variable=" strings. Fixes #151222.
1 parent cfd1ee7 commit aec90f2

File tree

6 files changed

+38
-4
lines changed

6 files changed

+38
-4
lines changed

flang-rt/include/flang-rt/runtime/descriptor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ class DescriptorAddendum {
101101
explicit RT_API_ATTRS DescriptorAddendum(
102102
const typeInfo::DerivedType *dt = nullptr)
103103
: derivedType_{dt}, len_{0} {}
104+
RT_API_ATTRS DescriptorAddendum(const DescriptorAddendum &that) {
105+
*this = that;
106+
}
104107
RT_API_ATTRS DescriptorAddendum &operator=(const DescriptorAddendum &);
105108

106109
RT_API_ATTRS const typeInfo::DerivedType *derivedType() const {

flang-rt/include/flang-rt/runtime/io-stmt.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,14 +461,16 @@ class ListDirectedStatementState<Direction::Input>
461461
inNamelistSequence_ = inNamelistSequence;
462462
}
463463

464+
protected:
465+
bool inNamelistSequence_{false};
466+
464467
private:
465468
int remaining_{0}; // for "r*" repetition
466469
Fortran::common::optional<SavedPosition> repeatPosition_;
467470
bool eatComma_{false}; // consume comma after previously read item
468471
bool hitSlash_{false}; // once '/' is seen, nullify further items
469472
bool realPart_{false};
470473
bool imaginaryPart_{false};
471-
bool inNamelistSequence_{false};
472474
};
473475

474476
template <Direction DIR>
@@ -688,7 +690,8 @@ template <Direction DIR>
688690
class ChildListIoStatementState : public ChildIoStatementState<DIR>,
689691
public ListDirectedStatementState<DIR> {
690692
public:
691-
using ChildIoStatementState<DIR>::ChildIoStatementState;
693+
RT_API_ATTRS ChildListIoStatementState(
694+
ChildIo &, const char *sourceFile = nullptr, int sourceLine = 0);
692695
using ListDirectedStatementState<DIR>::GetNextDataEdit;
693696
RT_API_ATTRS int EndIoStatement();
694697
};

flang-rt/lib/runtime/descriptor-io.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static RT_API_ATTRS Fortran::common::optional<bool> DefinedFormattedIo(
110110
Fortran::common::optional<std::int64_t> startPos;
111111
if (edit.descriptor == DataEdit::DefinedDerivedType &&
112112
special.which() == typeInfo::SpecialBinding::Which::ReadFormatted) {
113-
// DT is an edit descriptor so everything that the child
113+
// DT is an edit descriptor, so everything that the child
114114
// I/O subroutine reads counts towards READ(SIZE=).
115115
startPos = io.InquirePos();
116116
}

flang-rt/lib/runtime/descriptor.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ RT_API_ATTRS bool Descriptor::EstablishPointerSection(const Descriptor &source,
231231
const SubscriptValue *stride) {
232232
*this = source;
233233
raw_.attribute = CFI_attribute_pointer;
234+
SetAllocIdx(source.GetAllocIdx());
234235
int newRank{raw_.rank};
235236
for (int j{0}; j < raw_.rank; ++j) {
236237
if (!stride || stride[j] == 0) {
@@ -242,14 +243,17 @@ RT_API_ATTRS bool Descriptor::EstablishPointerSection(const Descriptor &source,
242243
}
243244
}
244245
raw_.rank = newRank;
246+
if (CFI_section(&raw_, &source.raw_, lower, upper, stride) != CFI_SUCCESS) {
247+
return false;
248+
}
245249
if (const auto *sourceAddendum = source.Addendum()) {
246250
if (auto *addendum{Addendum()}) {
247251
*addendum = *sourceAddendum;
248252
} else {
249253
return false;
250254
}
251255
}
252-
return CFI_section(&raw_, &source.raw_, lower, upper, stride) == CFI_SUCCESS;
256+
return true;
253257
}
254258

255259
RT_API_ATTRS void Descriptor::ApplyMold(

flang-rt/lib/runtime/io-stmt.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,22 @@ bool ChildFormattedIoStatementState<DIR, CHAR>::AdvanceRecord(int n) {
10781078
#endif
10791079
}
10801080

1081+
template <Direction DIR>
1082+
ChildListIoStatementState<DIR>::ChildListIoStatementState(
1083+
ChildIo &child, const char *sourceFile, int sourceLine)
1084+
: ChildIoStatementState<DIR>{child, sourceFile, sourceLine} {
1085+
#if !defined(RT_DEVICE_AVOID_RECURSION)
1086+
if constexpr (DIR == Direction::Input) {
1087+
if (auto *listInput{child.parent()
1088+
.get_if<ListDirectedStatementState<Direction::Input>>()}) {
1089+
this->inNamelistSequence_ = listInput->inNamelistSequence();
1090+
}
1091+
}
1092+
#else
1093+
this->ReportUnsupportedChildIo();
1094+
#endif
1095+
}
1096+
10811097
template <Direction DIR>
10821098
bool ChildUnformattedIoStatementState<DIR>::Receive(
10831099
char *data, std::size_t bytes, std::size_t elementBytes) {

flang-rt/lib/runtime/namelist.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,13 +268,21 @@ static RT_API_ATTRS void StorageSequenceExtension(
268268
? source.GetDimension(0).ByteStride()
269269
: static_cast<SubscriptValue>(source.ElementBytes())};
270270
stride != 0) {
271+
common::optional<DescriptorAddendum> savedAddendum;
272+
if (const DescriptorAddendum *addendum{desc.Addendum()}) {
273+
// Preserve a copy of the addendum, if any, before clobbering it
274+
savedAddendum.emplace(*addendum);
275+
}
271276
desc.raw().attribute = CFI_attribute_pointer;
272277
desc.raw().rank = 1;
273278
desc.GetDimension(0)
274279
.SetBounds(1,
275280
source.Elements() -
276281
((source.OffsetElement() - desc.OffsetElement()) / stride))
277282
.SetByteStride(stride);
283+
if (savedAddendum) {
284+
*desc.Addendum() = *savedAddendum;
285+
}
278286
}
279287
}
280288
}

0 commit comments

Comments
 (0)