Skip to content

Commit 750c8e3

Browse files
authored
[flang][runtime] Handle incomplete NAMELIST input derived type compon… (#66831)
…ent list When a derived type value appears in NAMELIST input, its components' values appear in sequence. This sequence can be truncated by a NAME= that begins the next NAMELIST input item, or by the terminal '/' that ends the NAMELIST group. Extend the mechanism already in place for truncated array item lists in NAMELIST input so that it also applies to derived type component sequences, and rename things appropriately.
1 parent 6f41510 commit 750c8e3

File tree

3 files changed

+16
-10
lines changed

3 files changed

+16
-10
lines changed

flang/runtime/descriptor-io.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,11 @@ static bool DefaultComponentwiseIO(IoStatementState &io,
288288
*compArray.Element<typeInfo::Component>(at)};
289289
if (!DefaultComponentIO<DIR>(
290290
io, component, descriptor, subscripts, handler, table)) {
291-
return false;
291+
// Truncated nonempty namelist input sequence?
292+
auto *listInput{
293+
io.get_if<ListDirectedStatementState<Direction::Input>>()};
294+
return DIR == Direction::Input && (j > 0 || k > 0) && listInput &&
295+
listInput->inNamelistSequence();
292296
}
293297
}
294298
}

flang/runtime/io-stmt.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,7 @@ template <>
295295
class ListDirectedStatementState<Direction::Input>
296296
: public FormattedIoStatementState<Direction::Input> {
297297
public:
298-
bool inNamelistArray() const { return inNamelistArray_; }
299-
void set_inNamelistArray(bool yes = true) { inNamelistArray_ = yes; }
298+
bool inNamelistSequence() const { return inNamelistSequence_; }
300299

301300
// Skips value separators, handles repetition and null values.
302301
// Vacant when '/' appears; present with descriptor == ListDirectedNullValue
@@ -308,11 +307,11 @@ class ListDirectedStatementState<Direction::Input>
308307
// input statement. This member function resets some state so that
309308
// repetition and null values work correctly for each successive
310309
// NAMELIST input item.
311-
void ResetForNextNamelistItem(bool inNamelistArray) {
310+
void ResetForNextNamelistItem(bool inNamelistSequence) {
312311
remaining_ = 0;
313312
eatComma_ = false;
314313
realPart_ = imaginaryPart_ = false;
315-
inNamelistArray_ = inNamelistArray;
314+
inNamelistSequence_ = inNamelistSequence;
316315
}
317316

318317
private:
@@ -322,7 +321,7 @@ class ListDirectedStatementState<Direction::Input>
322321
bool hitSlash_{false}; // once '/' is seen, nullify further items
323322
bool realPart_{false};
324323
bool imaginaryPart_{false};
325-
bool inNamelistArray_{false};
324+
bool inNamelistSequence_{false};
326325
};
327326

328327
template <Direction DIR>

flang/runtime/namelist.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,15 +522,18 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
522522
}
523523
io.HandleRelativePosition(byteCount);
524524
// Read the values into the descriptor. An array can be short.
525-
listInput->ResetForNextNamelistItem(useDescriptor->rank() > 0);
526525
if (const auto *addendum{useDescriptor->Addendum()};
527526
addendum && addendum->derivedType()) {
528527
const NonTbpDefinedIoTable *table{group.nonTbpDefinedIo};
528+
listInput->ResetForNextNamelistItem(/*inNamelistSequence=*/true);
529529
if (!IONAME(InputDerivedType)(cookie, *useDescriptor, table)) {
530530
return false;
531531
}
532-
} else if (!descr::DescriptorIO<Direction::Input>(io, *useDescriptor)) {
533-
return false;
532+
} else {
533+
listInput->ResetForNextNamelistItem(useDescriptor->rank() > 0);
534+
if (!descr::DescriptorIO<Direction::Input>(io, *useDescriptor)) {
535+
return false;
536+
}
534537
}
535538
next = io.GetNextNonBlank(byteCount);
536539
if (next && *next == comma) {
@@ -549,7 +552,7 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
549552
bool IsNamelistNameOrSlash(IoStatementState &io) {
550553
if (auto *listInput{
551554
io.get_if<ListDirectedStatementState<Direction::Input>>()}) {
552-
if (listInput->inNamelistArray()) {
555+
if (listInput->inNamelistSequence()) {
553556
SavedPosition savedPosition{io};
554557
std::size_t byteCount{0};
555558
if (auto ch{io.GetNextNonBlank(byteCount)}) {

0 commit comments

Comments
 (0)