summaryrefslogtreecommitdiff
path: root/flang-rt
diff options
context:
space:
mode:
authorPeter Klausler <pklausler@nvidia.com>2025-11-14 08:24:08 -0800
committerGitHub <noreply@github.com>2025-11-14 08:24:08 -0800
commita284ce8e0c9f409f4113007dd1e634f291a33746 (patch)
treee0a2079e63bccb82fa0a7d58590cb7f71ad8aac4 /flang-rt
parent3425f226fcc8a83dac1d02aa42c75fd3105a8d61 (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.h8
-rw-r--r--flang-rt/include/flang-rt/runtime/format-implementation.h9
-rw-r--r--flang-rt/include/flang-rt/runtime/io-error.h2
-rw-r--r--flang-rt/include/flang-rt/runtime/iostat.h23
-rw-r--r--flang-rt/lib/runtime/iostat.cpp2
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