[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