From 9a7a16c8d5a5927bfadd05e01c288a4fada00830 Mon Sep 17 00:00:00 2001 From: Peter Klausler Date: Mon, 18 Aug 2025 14:44:48 -0700 Subject: [PATCH] [flang][runtime] Allow child NAMELIST input to advance records (#153963) NAMELIST input in child I/O is rare, and it's not clear in the standard whether it should be allowed to advance to later records in the parent unit. But GNU Fortran supports it, and there's no good reason not to do so since a NAMELIST input group that isn't terminated on the same line is otherwise going to be a fatal error. Fixes https://github.com/llvm/llvm-project/issues/153416. --- flang-rt/include/flang-rt/runtime/io-stmt.h | 1 + flang-rt/lib/runtime/io-stmt.cpp | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/flang-rt/include/flang-rt/runtime/io-stmt.h b/flang-rt/include/flang-rt/runtime/io-stmt.h index 7693b60cccfc..3d1ca5091e92 100644 --- a/flang-rt/include/flang-rt/runtime/io-stmt.h +++ b/flang-rt/include/flang-rt/runtime/io-stmt.h @@ -696,6 +696,7 @@ public: RT_API_ATTRS ChildListIoStatementState( ChildIo &, const char *sourceFile = nullptr, int sourceLine = 0); using ListDirectedStatementState::GetNextDataEdit; + RT_API_ATTRS bool AdvanceRecord(int = 1); RT_API_ATTRS int EndIoStatement(); }; diff --git a/flang-rt/lib/runtime/io-stmt.cpp b/flang-rt/lib/runtime/io-stmt.cpp index c462f60b6b01..28149090eb16 100644 --- a/flang-rt/lib/runtime/io-stmt.cpp +++ b/flang-rt/lib/runtime/io-stmt.cpp @@ -1106,10 +1106,14 @@ ChildListIoStatementState::ChildListIoStatementState( } template -bool ChildUnformattedIoStatementState::Receive( - char *data, std::size_t bytes, std::size_t elementBytes) { +bool ChildListIoStatementState::AdvanceRecord(int n) { #if !defined(RT_DEVICE_AVOID_RECURSION) - return this->child().parent().Receive(data, bytes, elementBytes); + // Allow child NAMELIST input to advance + if (DIR == Direction::Input && this->mutableModes().inNamelist) { + return this->child().parent().AdvanceRecord(n); + } else { + return false; + } #else this->ReportUnsupportedChildIo(); #endif @@ -1125,6 +1129,16 @@ template int ChildListIoStatementState::EndIoStatement() { return ChildIoStatementState::EndIoStatement(); } +template +bool ChildUnformattedIoStatementState::Receive( + char *data, std::size_t bytes, std::size_t elementBytes) { +#if !defined(RT_DEVICE_AVOID_RECURSION) + return this->child().parent().Receive(data, bytes, elementBytes); +#else + this->ReportUnsupportedChildIo(); +#endif +} + template class InternalIoStatementState; template class InternalIoStatementState; template class InternalFormattedIoStatementState;