Index: flang/runtime/io-api.cpp =================================================================== --- flang/runtime/io-api.cpp +++ flang/runtime/io-api.cpp @@ -579,8 +579,9 @@ if (auto *unit{io.GetExternalFileUnit()}) { unit->SetPosition(pos - 1, handler); return true; + } else if (!io.get_if()) { + io.GetIoErrorHandler().Crash("SetPos() called on internal unit"); } - io.GetIoErrorHandler().Crash("SetPos() called on internal unit"); return false; } @@ -660,8 +661,11 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "SetAccess() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetAccess() called when not in an OPEN statement"); + } + return false; } else if (open->completedOperation()) { io.GetIoErrorHandler().Crash( "SetAccess() called after GetNewUnit() for an OPEN statement"); @@ -692,8 +696,11 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "SetAction() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetAction() called when not in an OPEN statement"); + } + return false; } else if (open->completedOperation()) { io.GetIoErrorHandler().Crash( "SetAction() called after GetNewUnit() for an OPEN statement"); @@ -741,7 +748,7 @@ if (isYes && !unit->mayAsynchronous()) { handler.SignalError(IostatBadAsynchronous); } - } else { + } else if (!io.get_if()) { handler.Crash("SetAsynchronous() called when not in an OPEN or external " "I/O statement"); } @@ -753,8 +760,11 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "SetCarriageControl() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetCarriageControl() called when not in an OPEN statement"); + } + return false; } else if (open->completedOperation()) { io.GetIoErrorHandler().Crash( "SetCarriageControl() called after GetNewUnit() for an OPEN statement"); @@ -781,8 +791,11 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "SetConvert() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetConvert() called when not in an OPEN statement"); + } + return false; } else if (open->completedOperation()) { io.GetIoErrorHandler().Crash( "SetConvert() called after GetNewUnit() for an OPEN statement"); @@ -802,8 +815,11 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "SetEncoding() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetEncoding() called when not in an OPEN statement"); + } + return false; } else if (open->completedOperation()) { io.GetIoErrorHandler().Crash( "SetEncoding() called after GetNewUnit() for an OPEN statement"); @@ -834,8 +850,10 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "SetForm() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetForm() called when not in an OPEN statement"); + } } else if (open->completedOperation()) { io.GetIoErrorHandler().Crash( "SetForm() called after GetNewUnit() for an OPEN statement"); @@ -860,8 +878,11 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "SetPosition() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetPosition() called when not in an OPEN statement"); + } + return false; } else if (open->completedOperation()) { io.GetIoErrorHandler().Crash( "SetPosition() called after GetNewUnit() for an OPEN statement"); @@ -888,8 +909,11 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "SetRecl() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetRecl() called when not in an OPEN statement"); + } + return false; } else if (open->completedOperation()) { io.GetIoErrorHandler().Crash( "SetRecl() called after GetNewUnit() for an OPEN statement"); @@ -953,7 +977,8 @@ } return false; } - if (io.get_if()) { + if (io.get_if() || + io.get_if()) { return true; // don't bother validating STATUS= in a no-op CLOSE } io.GetIoErrorHandler().Crash( @@ -969,9 +994,10 @@ } open->set_path(path, chars); return true; + } else if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "SetFile() called when not in an OPEN statement"); } - io.GetIoErrorHandler().Crash( - "SetFile() called when not in an OPEN statement"); return false; } @@ -979,8 +1005,11 @@ IoStatementState &io{*cookie}; auto *open{io.get_if()}; if (!open) { - io.GetIoErrorHandler().Crash( - "GetNewUnit() called when not in an OPEN statement"); + if (!io.get_if()) { + io.GetIoErrorHandler().Crash( + "GetNewUnit() called when not in an OPEN statement"); + } + return false; } else if (!open->InError()) { open->CompleteOperation(); } @@ -1015,9 +1044,10 @@ return unf->Emit(x, length, elementBytes); } else if (auto *inq{io.get_if()}) { return inq->Emit(x, length, elementBytes); + } else if (!io.get_if()) { + io.GetIoErrorHandler().Crash("OutputUnformattedBlock() called for an I/O " + "statement that is not unformatted output"); } - io.GetIoErrorHandler().Crash("OutputUnformattedBlock() called for an I/O " - "statement that is not unformatted output"); return false; } @@ -1032,14 +1062,17 @@ if (auto *unf{ io.get_if>()}) { return unf->Receive(x, length, elementBytes); + } else if (!io.get_if()) { + handler.Crash("InputUnformattedBlock() called for an I/O statement that is " + "not unformatted input"); } - handler.Crash("InputUnformattedBlock() called for an I/O statement that is " - "not unformatted input"); return false; } bool IONAME(OutputInteger8)(Cookie cookie, std::int8_t n) { - cookie->CheckFormattedStmtType("OutputInteger8"); + if (!cookie->CheckFormattedStmtType("OutputInteger8")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1048,7 +1081,9 @@ } bool IONAME(OutputInteger16)(Cookie cookie, std::int16_t n) { - cookie->CheckFormattedStmtType("OutputInteger16"); + if (!cookie->CheckFormattedStmtType("OutputInteger16")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1057,7 +1092,9 @@ } bool IONAME(OutputInteger32)(Cookie cookie, std::int32_t n) { - cookie->CheckFormattedStmtType("OutputInteger32"); + if (!cookie->CheckFormattedStmtType("OutputInteger32")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1066,7 +1103,9 @@ } bool IONAME(OutputInteger64)(Cookie cookie, std::int64_t n) { - cookie->CheckFormattedStmtType("OutputInteger64"); + if (!cookie->CheckFormattedStmtType("OutputInteger64")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1076,7 +1115,9 @@ #ifdef __SIZEOF_INT128__ bool IONAME(OutputInteger128)(Cookie cookie, common::int128_t n) { - cookie->CheckFormattedStmtType("OutputInteger128"); + if (!cookie->CheckFormattedStmtType("OutputInteger128")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1086,7 +1127,9 @@ #endif bool IONAME(InputInteger)(Cookie cookie, std::int64_t &n, int kind) { - cookie->CheckFormattedStmtType("InputInteger"); + if (!cookie->CheckFormattedStmtType("InputInteger")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1095,7 +1138,9 @@ } bool IONAME(OutputReal32)(Cookie cookie, float x) { - cookie->CheckFormattedStmtType("OutputReal32"); + if (!cookie->CheckFormattedStmtType("OutputReal32")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish(TypeCategory::Real, 4, reinterpret_cast(&x), 0); @@ -1103,7 +1148,9 @@ } bool IONAME(OutputReal64)(Cookie cookie, double x) { - cookie->CheckFormattedStmtType("OutputReal64"); + if (!cookie->CheckFormattedStmtType("OutputReal64")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish(TypeCategory::Real, 8, reinterpret_cast(&x), 0); @@ -1111,7 +1158,9 @@ } bool IONAME(InputReal32)(Cookie cookie, float &x) { - cookie->CheckFormattedStmtType("InputReal32"); + if (!cookie->CheckFormattedStmtType("InputReal32")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish(TypeCategory::Real, 4, reinterpret_cast(&x), 0); @@ -1119,7 +1168,9 @@ } bool IONAME(InputReal64)(Cookie cookie, double &x) { - cookie->CheckFormattedStmtType("InputReal64"); + if (!cookie->CheckFormattedStmtType("InputReal64")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish(TypeCategory::Real, 8, reinterpret_cast(&x), 0); @@ -1127,7 +1178,9 @@ } bool IONAME(OutputComplex32)(Cookie cookie, float r, float i) { - cookie->CheckFormattedStmtType("OutputComplex32"); + if (!cookie->CheckFormattedStmtType("OutputComplex32")) { + return false; + } float z[2]{r, i}; StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; @@ -1137,7 +1190,9 @@ } bool IONAME(OutputComplex64)(Cookie cookie, double r, double i) { - cookie->CheckFormattedStmtType("OutputComplex64"); + if (!cookie->CheckFormattedStmtType("OutputComplex64")) { + return false; + } double z[2]{r, i}; StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; @@ -1147,7 +1202,9 @@ } bool IONAME(InputComplex32)(Cookie cookie, float z[2]) { - cookie->CheckFormattedStmtType("InputComplex32"); + if (!cookie->CheckFormattedStmtType("InputComplex32")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1156,7 +1213,9 @@ } bool IONAME(InputComplex64)(Cookie cookie, double z[2]) { - cookie->CheckFormattedStmtType("InputComplex64"); + if (!cookie->CheckFormattedStmtType("InputComplex64")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1166,7 +1225,9 @@ bool IONAME(OutputCharacter)( Cookie cookie, const char *x, std::size_t length, int kind) { - cookie->CheckFormattedStmtType("OutputCharacter"); + if (!cookie->CheckFormattedStmtType("OutputCharacter")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1180,7 +1241,9 @@ bool IONAME(InputCharacter)( Cookie cookie, char *x, std::size_t length, int kind) { - cookie->CheckFormattedStmtType("InputCharacter"); + if (!cookie->CheckFormattedStmtType("InputCharacter")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish(kind, length, reinterpret_cast(x), 0); @@ -1192,7 +1255,9 @@ } bool IONAME(OutputLogical)(Cookie cookie, bool truth) { - cookie->CheckFormattedStmtType("OutputLogical"); + if (!cookie->CheckFormattedStmtType("OutputLogical")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1201,7 +1266,9 @@ } bool IONAME(InputLogical)(Cookie cookie, bool &truth) { - cookie->CheckFormattedStmtType("InputLogical"); + if (!cookie->CheckFormattedStmtType("InputLogical")) { + return false; + } StaticDescriptor staticDescriptor; Descriptor &descriptor{staticDescriptor.descriptor()}; descriptor.Establish( @@ -1218,9 +1285,10 @@ if (const auto *formatted{ io.get_if>()}) { return formatted->GetEditDescriptorChars(); + } else if (!io.get_if()) { + handler.Crash("GetIoSize() called for an I/O statement that is not a " + "formatted READ()"); } - handler.Crash( - "GetIoSize() called for an I/O statement that is not a formatted READ()"); return 0; } @@ -1232,9 +1300,10 @@ } if (const auto *inq{io.get_if()}) { return inq->bytes(); + } else if (!io.get_if()) { + handler.Crash("GetIoLength() called for an I/O statement that is not " + "INQUIRE(IOLENGTH=)"); } - handler.Crash("GetIoLength() called for an I/O statement that is not " - "INQUIRE(IOLENGTH=)"); return 0; } Index: flang/runtime/io-stmt.h =================================================================== --- flang/runtime/io-stmt.h +++ flang/runtime/io-stmt.h @@ -194,11 +194,16 @@ return ch; } - template void CheckFormattedStmtType(const char *name) { - if (!get_if>()) { - GetIoErrorHandler().Crash( - "%s called for I/O statement that is not formatted %s", name, - D == Direction::Output ? "output" : "input"); + template bool CheckFormattedStmtType(const char *name) { + if (get_if>()) { + return true; + } else { + if (!get_if()) { + GetIoErrorHandler().Crash( + "%s called for I/O statement that is not formatted %s", name, + D == Direction::Output ? "output" : "input"); + } + return false; } }