diff options
| author | Peter Klausler <pklausler@nvidia.com> | 2025-11-14 08:24:08 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-14 08:24:08 -0800 |
| commit | a284ce8e0c9f409f4113007dd1e634f291a33746 (patch) | |
| tree | e0a2079e63bccb82fa0a7d58590cb7f71ad8aac4 /flang-rt | |
| parent | 3425f226fcc8a83dac1d02aa42c75fd3105a8d61 (diff) | |
[flang][runtime] Advance output record in specific case (#167786)
When a formatted WRITE takes place in a defined output subroutine called
from a context in which record advancement is allowed, such as NAMELIST,
the char-string-edit-descs in the format can trigger record advancement.
Also clean up confusing messiness lingering from the separation of
iostat.h two headers in flang/.../Runtime. iostat.h didn't need to be
put into flang/.../Runtime since it's included only by flang-rt, and
iostat-consts.h doesn't need one of its includes.
Fixes https://github.com/llvm/llvm-project/issues/167757.
Diffstat (limited to 'flang-rt')
| -rw-r--r-- | flang-rt/include/flang-rt/runtime/connection.h | 8 | ||||
| -rw-r--r-- | flang-rt/include/flang-rt/runtime/format-implementation.h | 9 | ||||
| -rw-r--r-- | flang-rt/include/flang-rt/runtime/io-error.h | 2 | ||||
| -rw-r--r-- | flang-rt/include/flang-rt/runtime/iostat.h | 23 | ||||
| -rw-r--r-- | flang-rt/lib/runtime/iostat.cpp | 2 |
5 files changed, 42 insertions, 2 deletions
diff --git a/flang-rt/include/flang-rt/runtime/connection.h b/flang-rt/include/flang-rt/runtime/connection.h index 158e156d1b0b..3e783af1fa74 100644 --- a/flang-rt/include/flang-rt/runtime/connection.h +++ b/flang-rt/include/flang-rt/runtime/connection.h @@ -66,6 +66,14 @@ struct ConnectionState : public ConnectionAttributes { RT_API_ATTRS bool NeedAdvance(std::size_t width) const { return positionInRecord > 0 && width > RemainingSpaceInRecord(); } + RT_API_ATTRS bool NeedHardAdvance(std::size_t width) const { + auto recl{recordLength}; + if (!recl) { + recl = openRecl; + } + return recl && positionInRecord > 0 && + static_cast<std::int64_t>(positionInRecord + width) > *recl; + } RT_API_ATTRS void HandleAbsolutePosition(std::int64_t n) { positionInRecord = (n < 0 ? 0 : n) + leftTabLimit.value_or(0); } diff --git a/flang-rt/include/flang-rt/runtime/format-implementation.h b/flang-rt/include/flang-rt/runtime/format-implementation.h index 46134146f5c1..d510adbb5ba4 100644 --- a/flang-rt/include/flang-rt/runtime/format-implementation.h +++ b/flang-rt/include/flang-rt/runtime/format-implementation.h @@ -430,6 +430,9 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit( if constexpr (std::is_base_of_v<InputStatementState, CONTEXT>) { context.HandleRelativePosition(chars); } else { + if (context.GetConnectionState().NeedHardAdvance(chars)) { + context.AdvanceRecord(); + } EmitAscii(context, format_ + start, chars); } } else if (ch == 'H') { @@ -442,6 +445,9 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit( if constexpr (std::is_base_of_v<InputStatementState, CONTEXT>) { context.HandleRelativePosition(static_cast<std::size_t>(*repeat)); } else { + if (context.GetConnectionState().NeedHardAdvance(*repeat)) { + context.AdvanceRecord(); + } EmitAscii( context, format_ + offset_, static_cast<std::size_t>(*repeat)); } @@ -487,6 +493,9 @@ RT_API_ATTRS int FormatControl<CONTEXT>::CueUpNextDataEdit( } else if (ch == '\t' || ch == '\v') { // Tabs (extension) // TODO: any other raw characters? + if (context.GetConnectionState().NeedHardAdvance(1)) { + context.AdvanceRecord(); + } EmitAscii(context, format_ + offset_ - 1, 1); } else { ReportBadFormat( diff --git a/flang-rt/include/flang-rt/runtime/io-error.h b/flang-rt/include/flang-rt/runtime/io-error.h index 0ac118313180..d2180a83f8c3 100644 --- a/flang-rt/include/flang-rt/runtime/io-error.h +++ b/flang-rt/include/flang-rt/runtime/io-error.h @@ -15,9 +15,9 @@ #ifndef FLANG_RT_RUNTIME_IO_ERROR_H_ #define FLANG_RT_RUNTIME_IO_ERROR_H_ +#include "iostat.h" #include "memory.h" #include "terminator.h" -#include "flang/Runtime/iostat.h" #include <cinttypes> namespace Fortran::runtime::io { diff --git a/flang-rt/include/flang-rt/runtime/iostat.h b/flang-rt/include/flang-rt/runtime/iostat.h new file mode 100644 index 000000000000..44ddd0e72fee --- /dev/null +++ b/flang-rt/include/flang-rt/runtime/iostat.h @@ -0,0 +1,23 @@ +//===-- include/flang-rt/runtime/iostat.h -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// Defines the values returned by the runtime for IOSTAT= specifiers +// on I/O statements. + +#ifndef FORTRAN_RUNTIME_IOSTAT_H_ +#define FORTRAN_RUNTIME_IOSTAT_H_ + +#include "flang/Common/api-attrs.h" +#include "flang/Runtime/iostat-consts.h" + +namespace Fortran::runtime::io { + +RT_API_ATTRS const char *IostatErrorString(int); + +} // namespace Fortran::runtime::io +#endif // FORTRAN_RUNTIME_IOSTAT_H_ diff --git a/flang-rt/lib/runtime/iostat.cpp b/flang-rt/lib/runtime/iostat.cpp index 0f8bfb884e54..c2577e7caf0e 100644 --- a/flang-rt/lib/runtime/iostat.cpp +++ b/flang-rt/lib/runtime/iostat.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "flang/Runtime/iostat.h" +#include "flang-rt/runtime/iostat.h" namespace Fortran::runtime::io { RT_OFFLOAD_API_GROUP_BEGIN |
