[flang-commits] [flang] a62b601 - [flang] Predefine unit 0 connected to stderr
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Mon Nov 22 09:02:47 PST 2021
Author: Peter Klausler
Date: 2021-11-22T09:02:39-08:00
New Revision: a62b60167ddbc23602ea20d65a41b2cd1ce5953a
URL: https://github.com/llvm/llvm-project/commit/a62b60167ddbc23602ea20d65a41b2cd1ce5953a
DIFF: https://github.com/llvm/llvm-project/commit/a62b60167ddbc23602ea20d65a41b2cd1ce5953a.diff
LOG: [flang] Predefine unit 0 connected to stderr
This is a near-universal language extension; external unit 0
is preconnected to the standard error output.
Differential Revision: https://reviews.llvm.org/D114298
Added:
Modified:
flang/docs/Extensions.md
flang/module/iso_fortran_env.f90
flang/runtime/unit.cpp
Removed:
################################################################################
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 02276fbe45e52..3c63d83aacc4f 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -188,6 +188,8 @@ end
if an actual argument acceptable to one could not be passed to
the other & vice versa because exactly one is polymorphic or
exactly one is unlimited polymorphic).
+* External unit 0 is predefined and connected to the standard error output,
+ and defined as `ERROR_UNIT` in the intrinsic `ISO_FORTRAN_ENV` module.
### Extensions supported when enabled by options
diff --git a/flang/module/iso_fortran_env.f90 b/flang/module/iso_fortran_env.f90
index 3d77485c13e31..e85d2e2a7a36c 100644
--- a/flang/module/iso_fortran_env.f90
+++ b/flang/module/iso_fortran_env.f90
@@ -129,7 +129,7 @@ module iso_fortran_env
integer, parameter :: current_team = -1, initial_team = -2, parent_team = -3
integer, parameter :: input_unit = 5, output_unit = 6
- integer, parameter :: error_unit = output_unit
+ integer, parameter :: error_unit = 0
integer, parameter :: iostat_end = -1, iostat_eor = -2
integer, parameter :: iostat_inquire_internal_unit = -1
diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp
index 1c915f3b49753..e24914bc5fa68 100644
--- a/flang/runtime/unit.cpp
+++ b/flang/runtime/unit.cpp
@@ -21,19 +21,23 @@ namespace Fortran::runtime::io {
// should work without a Fortran main program.
static Lock unitMapLock;
static UnitMap *unitMap{nullptr};
-static ExternalFileUnit *defaultInput{nullptr};
-static ExternalFileUnit *defaultOutput{nullptr};
+static ExternalFileUnit *defaultInput{nullptr}; // unit 5
+static ExternalFileUnit *defaultOutput{nullptr}; // unit 6
+static ExternalFileUnit *errorOutput{nullptr}; // unit 0 extension
void FlushOutputOnCrash(const Terminator &terminator) {
- if (!defaultOutput) {
+ if (!defaultOutput && !errorOutput) {
return;
}
+ IoErrorHandler handler{terminator};
+ handler.HasIoStat(); // prevent nested crash if flush has error
CriticalSection critical{unitMapLock};
if (defaultOutput) {
- IoErrorHandler handler{terminator};
- handler.HasIoStat(); // prevent nested crash if flush has error
defaultOutput->FlushOutput(handler);
}
+ if (errorOutput) {
+ errorOutput->FlushOutput(handler);
+ }
}
ExternalFileUnit *ExternalFileUnit::LookUp(int unit) {
@@ -210,6 +214,7 @@ UnitMap &ExternalFileUnit::GetUnitMap() {
Terminator terminator{__FILE__, __LINE__};
IoErrorHandler handler{terminator};
UnitMap *newUnitMap{New<UnitMap>{terminator}().release()};
+
bool wasExtant{false};
ExternalFileUnit &out{newUnitMap->LookUpOrCreate(6, terminator, wasExtant)};
RUNTIME_CHECK(terminator, !wasExtant);
@@ -217,12 +222,21 @@ UnitMap &ExternalFileUnit::GetUnitMap() {
out.SetDirection(Direction::Output, handler);
out.isUnformatted = false;
defaultOutput = &out;
+
ExternalFileUnit &in{newUnitMap->LookUpOrCreate(5, terminator, wasExtant)};
RUNTIME_CHECK(terminator, !wasExtant);
in.Predefine(0);
in.SetDirection(Direction::Input, handler);
in.isUnformatted = false;
defaultInput = ∈
+
+ ExternalFileUnit &error{newUnitMap->LookUpOrCreate(0, terminator, wasExtant)};
+ RUNTIME_CHECK(terminator, !wasExtant);
+ error.Predefine(2);
+ error.SetDirection(Direction::Output, handler);
+ error.isUnformatted = false;
+ errorOutput = &error;
+
// TODO: Set UTF-8 mode from the environment
unitMap = newUnitMap;
return *unitMap;
@@ -235,6 +249,8 @@ void ExternalFileUnit::CloseAll(IoErrorHandler &handler) {
FreeMemoryAndNullify(unitMap);
}
defaultOutput = nullptr;
+ defaultInput = nullptr;
+ errorOutput = nullptr;
}
void ExternalFileUnit::FlushAll(IoErrorHandler &handler) {
@@ -627,8 +643,13 @@ void ExternalFileUnit::BeginSequentialVariableUnformattedInputRecord(
void ExternalFileUnit::BeginSequentialVariableFormattedInputRecord(
IoErrorHandler &handler) {
- if (this == defaultInput && defaultOutput) {
- defaultOutput->FlushOutput(handler);
+ if (this == defaultInput) {
+ if (defaultOutput) {
+ defaultOutput->FlushOutput(handler);
+ }
+ if (errorOutput) {
+ errorOutput->FlushOutput(handler);
+ }
}
std::size_t length{0};
do {
More information about the flang-commits
mailing list