[flang-commits] [flang] c078e46 - [flang][runtime] FLUSH(bad or unconnected unit number) is an error

Peter Klausler via flang-commits flang-commits at lists.llvm.org
Thu Jun 23 11:09:07 PDT 2022


Author: Peter Klausler
Date: 2022-06-23T11:08:53-07:00
New Revision: c078e464a09fa5a6df1d5b94fc862d2f9bf6b8bd

URL: https://github.com/llvm/llvm-project/commit/c078e464a09fa5a6df1d5b94fc862d2f9bf6b8bd
DIFF: https://github.com/llvm/llvm-project/commit/c078e464a09fa5a6df1d5b94fc862d2f9bf6b8bd.diff

LOG: [flang][runtime] FLUSH(bad or unconnected unit number) is an error

Some I/O control statements are no-ops when attempted on a bad or
unconnected UNIT=, but the standard says that FLUSH is an error
in that case.

Differential Revision: https://reviews.llvm.org/D128392

Added: 
    

Modified: 
    flang/include/flang/Runtime/iostat.h
    flang/runtime/io-api.cpp
    flang/runtime/iostat.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Runtime/iostat.h b/flang/include/flang/Runtime/iostat.h
index bd38e748e4a92..6d6be7c7b8d57 100644
--- a/flang/include/flang/Runtime/iostat.h
+++ b/flang/include/flang/Runtime/iostat.h
@@ -81,6 +81,7 @@ enum Iostat {
   IostatTooManyAsyncOps,
   IostatBadBackspaceUnit,
   IostatBadUnitNumber,
+  IostatBadFlushUnit,
 };
 
 const char *IostatErrorString(int);

diff  --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp
index f3efaa9635749..60e52e50c32bc 100644
--- a/flang/runtime/io-api.cpp
+++ b/flang/runtime/io-api.cpp
@@ -147,6 +147,18 @@ Cookie IONAME(BeginInternalFormattedInput)(const char *internal,
       format, formatLength, scratchArea, scratchBytes, sourceFile, sourceLine);
 }
 
+static Cookie NoopUnit(const Terminator &terminator, int unitNumber,
+    enum Iostat iostat = IostatOk) {
+  Cookie cookie{&New<NoopStatementState>{terminator}(
+      terminator.sourceFileName(), terminator.sourceLine(), unitNumber)
+                     .release()
+                     ->ioStatementState()};
+  if (iostat != IostatOk) {
+    cookie->GetIoErrorHandler().SetPendingError(iostat);
+  }
+  return cookie;
+}
+
 static ExternalFileUnit *GetOrCreateUnit(int unitNumber, Direction direction,
     std::optional<bool> isUnformatted, const Terminator &terminator,
     Cookie &errorCookie) {
@@ -156,11 +168,7 @@ static ExternalFileUnit *GetOrCreateUnit(int unitNumber, Direction direction,
     errorCookie = nullptr;
     return unit;
   } else {
-    errorCookie = &New<NoopStatementState>{terminator}(
-        terminator.sourceFileName(), terminator.sourceLine(), unitNumber)
-                       .release()
-                       ->ioStatementState();
-    errorCookie->GetIoErrorHandler().SetPendingError(IostatBadUnitNumber);
+    errorCookie = NoopUnit(terminator, unitNumber, IostatBadUnitNumber);
     return nullptr;
   }
 }
@@ -358,12 +366,7 @@ Cookie IONAME(BeginOpenUnit)( // OPEN(without NEWUNIT=)
     return &unit->BeginIoStatement<OpenStatementState>(
         *unit, wasExtant, sourceFile, sourceLine);
   } else {
-    auto &io{
-        New<NoopStatementState>{terminator}(sourceFile, sourceLine, unitNumber)
-            .release()
-            ->ioStatementState()};
-    io.GetIoErrorHandler().SetPendingError(IostatBadUnitNumber);
-    return &io;
+    return NoopUnit(terminator, unitNumber, IostatBadUnitNumber);
   }
 }
 
@@ -378,7 +381,6 @@ Cookie IONAME(BeginOpenNewUnit)( // OPEN(NEWUNIT=j)
 
 Cookie IONAME(BeginWait)(ExternalUnit unitNumber, AsynchronousId id,
     const char *sourceFile, int sourceLine) {
-  Terminator terminator{sourceFile, sourceLine};
   if (ExternalFileUnit * unit{ExternalFileUnit::LookUp(unitNumber)}) {
     if (unit->Wait(id)) {
       return &unit->BeginIoStatement<ExternalMiscIoStatementState>(
@@ -388,14 +390,9 @@ Cookie IONAME(BeginWait)(ExternalUnit unitNumber, AsynchronousId id,
           IostatBadWaitId, unit, sourceFile, sourceLine);
     }
   } else {
-    auto &io{
-        New<NoopStatementState>{terminator}(sourceFile, sourceLine, unitNumber)
-            .release()
-            ->ioStatementState()};
-    if (id != 0) {
-      io.GetIoErrorHandler().SetPendingError(IostatBadWaitUnit);
-    }
-    return &io;
+    Terminator terminator{sourceFile, sourceLine};
+    return NoopUnit(
+        terminator, unitNumber, id == 0 ? IostatOk : IostatBadWaitUnit);
   }
 }
 Cookie IONAME(BeginWaitAll)(
@@ -410,10 +407,8 @@ Cookie IONAME(BeginClose)(
         *unit, sourceFile, sourceLine);
   } else {
     // CLOSE(UNIT=bad unit) is just a no-op
-    Terminator oom{sourceFile, sourceLine};
-    return &New<NoopStatementState>{oom}(sourceFile, sourceLine, unitNumber)
-                .release()
-                ->ioStatementState();
+    Terminator terminator{sourceFile, sourceLine};
+    return NoopUnit(terminator, unitNumber);
   }
 }
 
@@ -423,11 +418,10 @@ Cookie IONAME(BeginFlush)(
     return &unit->BeginIoStatement<ExternalMiscIoStatementState>(
         *unit, ExternalMiscIoStatementState::Flush, sourceFile, sourceLine);
   } else {
-    // FLUSH(UNIT=unknown) is a no-op
-    Terminator oom{sourceFile, sourceLine};
-    return &New<NoopStatementState>{oom}(sourceFile, sourceLine, unitNumber)
-                .release()
-                ->ioStatementState();
+    // FLUSH(UNIT=bad unit) is an error; an unconnected unit is a no-op
+    Terminator terminator{sourceFile, sourceLine};
+    return NoopUnit(terminator, unitNumber,
+        unitNumber >= 0 ? IostatOk : IostatBadFlushUnit);
   }
 }
 
@@ -438,12 +432,7 @@ Cookie IONAME(BeginBackspace)(
     return &unit->BeginIoStatement<ExternalMiscIoStatementState>(
         *unit, ExternalMiscIoStatementState::Backspace, sourceFile, sourceLine);
   } else {
-    auto &io{
-        New<NoopStatementState>{terminator}(sourceFile, sourceLine, unitNumber)
-            .release()
-            ->ioStatementState()};
-    io.GetIoErrorHandler().SetPendingError(IostatBadBackspaceUnit);
-    return &io;
+    return NoopUnit(terminator, unitNumber, IostatBadBackspaceUnit);
   }
 }
 

diff  --git a/flang/runtime/iostat.cpp b/flang/runtime/iostat.cpp
index d39f9b64f5e65..747a776aae7cc 100644
--- a/flang/runtime/iostat.cpp
+++ b/flang/runtime/iostat.cpp
@@ -87,7 +87,7 @@ const char *IostatErrorString(int iostat) {
     return "READ/WRITE(ASYNCHRONOUS='YES') on unit without "
            "OPEN(ASYNCHRONOUS='YES')";
   case IostatBadWaitUnit:
-    return "WAIT(UNIT=) for a bad unit number";
+    return "WAIT(UNIT=) for a bad or unconnected unit number";
   case IostatBOZInputOverflow:
     return "B/O/Z input value overflows variable";
   case IostatIntegerInputOverflow:
@@ -107,6 +107,8 @@ const char *IostatErrorString(int iostat) {
     return "BACKSPACE on unconnected unit";
   case IostatBadUnitNumber:
     return "Negative unit number is not allowed";
+  case IostatBadFlushUnit:
+    return "FLUSH attempted on a bad or unconnected unit number";
   default:
     return nullptr;
   }


        


More information about the flang-commits mailing list