mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 11:02:04 +08:00
[flang][runtime] Allow some list-directed child output to advance (#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 https://github.com/llvm/llvm-project/issues/166804.
This commit is contained in:
@@ -730,8 +730,7 @@ public:
|
||||
RT_API_ATTRS bool AdvanceRecord(int = 1);
|
||||
RT_API_ATTRS int EndIoStatement();
|
||||
RT_API_ATTRS bool CanAdvance() {
|
||||
return DIR == Direction::Input &&
|
||||
(canAdvance_ || this->mutableModes().inNamelist);
|
||||
return canAdvance_ || this->mutableModes().inNamelist;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -175,9 +175,10 @@ bool RT_API_ATTRS EditIntegerOutput(IoStatementState &io, const DataEdit &edit,
|
||||
}
|
||||
if (edit.IsListDirected()) {
|
||||
int total{std::max(leadingSpaces, 1) + subTotal};
|
||||
if (io.GetConnectionState().NeedAdvance(static_cast<std::size_t>(total)) &&
|
||||
!io.AdvanceRecord()) {
|
||||
return false;
|
||||
if (io.GetConnectionState().NeedAdvance(static_cast<std::size_t>(total))) {
|
||||
if (!io.AdvanceRecord()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
leadingSpaces = 1;
|
||||
} else if (!edit.width) {
|
||||
|
||||
@@ -1109,20 +1109,20 @@ ChildListIoStatementState<DIR>::ChildListIoStatementState(
|
||||
ChildIo &child, const char *sourceFile, int sourceLine)
|
||||
: ChildIoStatementState<DIR>{child, sourceFile, sourceLine} {
|
||||
#if !defined(RT_DEVICE_AVOID_RECURSION)
|
||||
if constexpr (DIR == Direction::Input) {
|
||||
if (const auto *listInput{child.parent()
|
||||
.get_if<ListDirectedStatementState<Direction::Input>>()}) {
|
||||
this->set_eatComma(listInput->eatComma());
|
||||
this->namelistGroup_ = listInput->namelistGroup();
|
||||
if (auto *childListInput{child.parent()
|
||||
.get_if<ChildListIoStatementState<Direction::Input>>()}) {
|
||||
// Child list input whose parent is child list input: can advance
|
||||
// if the parent can.
|
||||
this->canAdvance_ = childListInput->CanAdvance();
|
||||
} else {
|
||||
// Child list input of top-level list input: can advance.
|
||||
this->canAdvance_ = true;
|
||||
}
|
||||
if (const auto *listParent{
|
||||
child.parent().get_if<ListDirectedStatementState<DIR>>()}) {
|
||||
if constexpr (DIR == Direction::Input) {
|
||||
this->set_eatComma(listParent->eatComma());
|
||||
this->namelistGroup_ = listParent->namelistGroup();
|
||||
}
|
||||
if (auto *childListParent{
|
||||
child.parent().get_if<ChildListIoStatementState<DIR>>()}) {
|
||||
// Child list I/O whose parent is child list I/O: can advance
|
||||
// if the parent can.
|
||||
this->canAdvance_ = childListParent->CanAdvance();
|
||||
} else {
|
||||
// Child list I/O of top-level list I/O: can advance.
|
||||
this->canAdvance_ = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user