Commit b1856009 authored by Peter Klausler's avatar Peter Klausler
Browse files

[flang] Allow INQUIRE() on a child unit in user-defined I/O procedure

A procedure that implements a user-defined derived type I/O operation
is allowed to perform an INQUIRE statement on its unit.

Differential Revision: https://reviews.llvm.org/D117905https://reviews.llvm.org/D117905
parent e796eaf2
...@@ -156,6 +156,13 @@ Cookie BeginExternalListIO(const char *what, int unitNumber, ...@@ -156,6 +156,13 @@ Cookie BeginExternalListIO(const char *what, int unitNumber,
} }
ExternalFileUnit &unit{ExternalFileUnit::LookUpOrCreateAnonymous( ExternalFileUnit &unit{ExternalFileUnit::LookUpOrCreateAnonymous(
unitNumber, DIR, false /*!unformatted*/, terminator)}; unitNumber, DIR, false /*!unformatted*/, terminator)};
if (!unit.isUnformatted.has_value()) {
unit.isUnformatted = false;
}
if (*unit.isUnformatted) {
terminator.Crash("%s attempted on unformatted file", what);
return nullptr;
}
if (ChildIo * child{unit.GetChildIo()}) { if (ChildIo * child{unit.GetChildIo()}) {
return child->CheckFormattingAndDirection(terminator, what, false, DIR) return child->CheckFormattingAndDirection(terminator, what, false, DIR)
? &child->BeginIoStatement<ChildListIoStatementState<DIR>>( ? &child->BeginIoStatement<ChildListIoStatementState<DIR>>(
...@@ -166,13 +173,6 @@ Cookie BeginExternalListIO(const char *what, int unitNumber, ...@@ -166,13 +173,6 @@ Cookie BeginExternalListIO(const char *what, int unitNumber,
terminator.Crash("%s attempted on direct access file", what); terminator.Crash("%s attempted on direct access file", what);
return nullptr; return nullptr;
} }
if (!unit.isUnformatted.has_value()) {
unit.isUnformatted = false;
}
if (*unit.isUnformatted) {
terminator.Crash("%s attempted on unformatted file", what);
return nullptr;
}
IoErrorHandler handler{terminator}; IoErrorHandler handler{terminator};
unit.SetDirection(DIR, handler); unit.SetDirection(DIR, handler);
IoStatementState &io{unit.BeginIoStatement<STATE<DIR>>( IoStatementState &io{unit.BeginIoStatement<STATE<DIR>>(
...@@ -202,6 +202,13 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength, ...@@ -202,6 +202,13 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength,
} }
ExternalFileUnit &unit{ExternalFileUnit::LookUpOrCreateAnonymous( ExternalFileUnit &unit{ExternalFileUnit::LookUpOrCreateAnonymous(
unitNumber, DIR, false /*!unformatted*/, terminator)}; unitNumber, DIR, false /*!unformatted*/, terminator)};
if (!unit.isUnformatted.has_value()) {
unit.isUnformatted = false;
}
if (*unit.isUnformatted) {
terminator.Crash("Formatted I/O attempted on unformatted file");
return nullptr;
}
if (ChildIo * child{unit.GetChildIo()}) { if (ChildIo * child{unit.GetChildIo()}) {
return child->CheckFormattingAndDirection(terminator, return child->CheckFormattingAndDirection(terminator,
DIR == Direction::Output ? "formatted output" DIR == Direction::Output ? "formatted output"
...@@ -211,13 +218,6 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength, ...@@ -211,13 +218,6 @@ Cookie BeginExternalFormattedIO(const char *format, std::size_t formatLength,
*child, sourceFile, sourceLine) *child, sourceFile, sourceLine)
: nullptr; : nullptr;
} else { } else {
if (!unit.isUnformatted.has_value()) {
unit.isUnformatted = false;
}
if (*unit.isUnformatted) {
terminator.Crash("Formatted I/O attempted on unformatted file");
return nullptr;
}
IoErrorHandler handler{terminator}; IoErrorHandler handler{terminator};
unit.SetDirection(DIR, handler); unit.SetDirection(DIR, handler);
IoStatementState &io{ IoStatementState &io{
...@@ -247,6 +247,12 @@ Cookie BeginUnformattedIO( ...@@ -247,6 +247,12 @@ Cookie BeginUnformattedIO(
Terminator terminator{sourceFile, sourceLine}; Terminator terminator{sourceFile, sourceLine};
ExternalFileUnit &unit{ExternalFileUnit::LookUpOrCreateAnonymous( ExternalFileUnit &unit{ExternalFileUnit::LookUpOrCreateAnonymous(
unitNumber, DIR, true /*unformatted*/, terminator)}; unitNumber, DIR, true /*unformatted*/, terminator)};
if (!unit.isUnformatted.has_value()) {
unit.isUnformatted = true;
}
if (!*unit.isUnformatted) {
terminator.Crash("Unformatted I/O attempted on formatted file");
}
if (ChildIo * child{unit.GetChildIo()}) { if (ChildIo * child{unit.GetChildIo()}) {
return child->CheckFormattingAndDirection(terminator, return child->CheckFormattingAndDirection(terminator,
DIR == Direction::Output ? "unformatted output" DIR == Direction::Output ? "unformatted output"
...@@ -256,12 +262,6 @@ Cookie BeginUnformattedIO( ...@@ -256,12 +262,6 @@ Cookie BeginUnformattedIO(
*child, sourceFile, sourceLine) *child, sourceFile, sourceLine)
: nullptr; : nullptr;
} else { } else {
if (!unit.isUnformatted.has_value()) {
unit.isUnformatted = true;
}
if (!*unit.isUnformatted) {
terminator.Crash("Unformatted I/O attempted on formatted file");
}
IoStatementState &io{ IoStatementState &io{
unit.BeginIoStatement<ExternalUnformattedIoStatementState<DIR>>( unit.BeginIoStatement<ExternalUnformattedIoStatementState<DIR>>(
unit, sourceFile, sourceLine)}; unit, sourceFile, sourceLine)};
...@@ -367,8 +367,13 @@ Cookie IONAME(BeginRewind)( ...@@ -367,8 +367,13 @@ Cookie IONAME(BeginRewind)(
Cookie IONAME(BeginInquireUnit)( Cookie IONAME(BeginInquireUnit)(
ExternalUnit unitNumber, const char *sourceFile, int sourceLine) { ExternalUnit unitNumber, const char *sourceFile, int sourceLine) {
if (ExternalFileUnit * unit{ExternalFileUnit::LookUp(unitNumber)}) { if (ExternalFileUnit * unit{ExternalFileUnit::LookUp(unitNumber)}) {
return &unit->BeginIoStatement<InquireUnitState>( if (ChildIo * child{unit->GetChildIo()}) {
*unit, sourceFile, sourceLine); return &child->BeginIoStatement<InquireUnitState>(
*unit, sourceFile, sourceLine);
} else {
return &unit->BeginIoStatement<InquireUnitState>(
*unit, sourceFile, sourceLine);
}
} else { } else {
// INQUIRE(UNIT=unrecognized unit) // INQUIRE(UNIT=unrecognized unit)
Terminator oom{sourceFile, sourceLine}; Terminator oom{sourceFile, sourceLine};
......
...@@ -183,7 +183,7 @@ private: ...@@ -183,7 +183,7 @@ private:
ChildListIoStatementState<Direction::Output>, ChildListIoStatementState<Direction::Output>,
ChildListIoStatementState<Direction::Input>, ChildListIoStatementState<Direction::Input>,
ChildUnformattedIoStatementState<Direction::Output>, ChildUnformattedIoStatementState<Direction::Output>,
ChildUnformattedIoStatementState<Direction::Input>> ChildUnformattedIoStatementState<Direction::Input>, InquireUnitState>
u_; u_;
std::optional<IoStatementState> io_; std::optional<IoStatementState> io_;
}; };
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment