Index: flang/include/flang/Runtime/iostat.h =================================================================== --- flang/include/flang/Runtime/iostat.h +++ flang/include/flang/Runtime/iostat.h @@ -70,6 +70,10 @@ IostatUnitOverflow, IostatBadRealInput, IostatBadScaleFactor, + IostatBadAsynchronous, + IostatBadWaitUnit, + IostatBOZInputOverflow, + IostatIntegerInputOverflow, }; const char *IostatErrorString(int); Index: flang/runtime/edit-input.cpp =================================================================== --- flang/runtime/edit-input.cpp +++ flang/runtime/edit-input.cpp @@ -47,7 +47,7 @@ } auto significantBytes{static_cast(digits * LOG2_BASE + 7) / 8}; if (significantBytes > bytes) { - io.GetIoErrorHandler().SignalError( + io.GetIoErrorHandler().SignalError(IostatBOZInputOverflow, "B/O/Z input of %d digits overflows %zd-byte variable", digits, bytes); return false; } @@ -140,6 +140,7 @@ bool negate{ScanNumericPrefix(io, edit, next, remaining)}; common::UnsignedInt128 value{0}; bool any{negate}; + bool overflow{false}; for (; next; next = io.NextInField(remaining, edit)) { char32_t ch{*next}; if (ch == ' ' || ch == '\t') { @@ -157,10 +158,23 @@ "Bad character '%lc' in INTEGER input field", ch); return false; } + static constexpr auto maxu128{~common::UnsignedInt128{0}}; + static constexpr auto maxu128OverTen{maxu128 / 10}; + static constexpr int maxLastDigit{ + static_cast(maxu128 - (maxu128OverTen * 10))}; + overflow |= value >= maxu128OverTen && + (value > maxu128OverTen || digit > maxLastDigit); value *= 10; value += digit; any = true; } + auto maxForKind{common::UnsignedInt128{1} << ((8 * kind) - 1)}; + overflow |= value >= maxForKind && (value > maxForKind || !negate); + if (overflow) { + io.GetIoErrorHandler().SignalError(IostatIntegerInputOverflow, + "Decimal input overflows INTEGER(%d) variable", kind); + return false; + } if (negate) { value = -value; } Index: flang/runtime/iostat.cpp =================================================================== --- flang/runtime/iostat.cpp +++ flang/runtime/iostat.cpp @@ -83,6 +83,15 @@ return "Bad REAL input value"; case IostatBadScaleFactor: return "Bad REAL output scale factor (kP)"; + case IostatBadAsynchronous: + return "READ/WRITE(ASYNCHRONOUS='YES') on unit without " + "OPEN(ASYNCHRONOUS='YES')"; + case IostatBadWaitUnit: + return "WAIT(ID=nonzero) for a bad unit number"; + case IostatBOZInputOverflow: + return "B/O/Z input value overflows variable"; + case IostatIntegerInputOverflow: + return "Integer input value overflows variable"; default: return nullptr; }