[flang-commits] [flang] [flang] EOF goes to ERR= in READ(..., REC=) (PR #122608)

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Sat Jan 11 11:14:09 PST 2025


https://github.com/klausler created https://github.com/llvm/llvm-project/pull/122608

A direct access READ that tries to read past the end of the file must recover the error via an ERR= label, not an END= label (which is not allowed to be present).

Fixes https://github.com/llvm/llvm-project/issues/122150.

>From 3ca0469d888ae92ad7095f5058d452058b6ef888 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Sat, 11 Jan 2025 11:11:24 -0800
Subject: [PATCH] [flang] EOF goes to ERR= in READ(..., REC=)

A direct access READ that tries to read past the end of the file
must recover the error via an ERR= label, not an END= label (which
is not allowed to be present).

Fixes https://github.com/llvm/llvm-project/issues/122150.
---
 flang/runtime/io-api.cpp   | 1 +
 flang/runtime/io-error.cpp | 4 +++-
 flang/runtime/io-error.h   | 2 ++
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp
index 39ac8c9eb6defb..7023f61ba34de7 100644
--- a/flang/runtime/io-api.cpp
+++ b/flang/runtime/io-api.cpp
@@ -623,6 +623,7 @@ bool IODEF(SetRec)(Cookie cookie, std::int64_t rec) {
       handler.SignalError(
           IostatBadOpOnChildUnit, "REC= specifier on child I/O");
     } else {
+      handler.HasRec();
       unit->SetDirectRec(rec, handler);
     }
   } else if (!io.get_if<ErroneousIoStatementState>()) {
diff --git a/flang/runtime/io-error.cpp b/flang/runtime/io-error.cpp
index 7a90966f81047f..37909e8e6dad2c 100644
--- a/flang/runtime/io-error.cpp
+++ b/flang/runtime/io-error.cpp
@@ -25,7 +25,9 @@ void IoErrorHandler::SignalError(int iostatOrErrno, const char *msg, ...) {
   case IostatOk:
     return;
   case IostatEnd:
-    if (flags_ & (hasIoStat | hasEnd)) {
+    if ((flags_ & (hasIoStat | hasEnd)) ||
+        ((flags_ & hasErr) && (flags_ & hasRec))) {
+      // EOF goes to ERR= when REC= is present
       if (ioStat_ == IostatOk || ioStat_ < IostatEnd) {
         ioStat_ = IostatEnd;
       }
diff --git a/flang/runtime/io-error.h b/flang/runtime/io-error.h
index 426573e2faf00c..39a343c8e0a516 100644
--- a/flang/runtime/io-error.h
+++ b/flang/runtime/io-error.h
@@ -33,6 +33,7 @@ class IoErrorHandler : public Terminator {
   RT_API_ATTRS void HasEndLabel() { flags_ |= hasEnd; }
   RT_API_ATTRS void HasEorLabel() { flags_ |= hasEor; }
   RT_API_ATTRS void HasIoMsg() { flags_ |= hasIoMsg; }
+  RT_API_ATTRS void HasRec() { flags_ |= hasRec; }
 
   RT_API_ATTRS bool InError() const {
     return ioStat_ != IostatOk || pendingError_ != IostatOk;
@@ -70,6 +71,7 @@ class IoErrorHandler : public Terminator {
     hasEnd = 4, // END=
     hasEor = 8, // EOR=
     hasIoMsg = 16, // IOMSG=
+    hasRec = 32, // REC=
   };
   std::uint8_t flags_{0};
   int ioStat_{IostatOk};



More information about the flang-commits mailing list