3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-08-02 20:23:27 +00:00

scanner: emit ERROR_TOKEN on I/O failure instead of silent EOF (#10294)

`scanner::scan()` was returning `EOF_TOKEN` when the underlying stream
had `badbit` set, making a failed read (EIO, ENOSPC, etc.)
indistinguishable from a clean end-of-file. Z3 would silently produce no
output with exit code 0.

## Root cause

`std::istream::gcount()` returns 0 for both normal EOF and I/O failure.
`read_char()` returned -1 in both cases, and `scan()`'s `-1` handler
unconditionally set `EOF_TOKEN`.

## Fix

### `src/parsers/util/scanner.cpp`
Check `m_stream.bad()` in the `-1` case; emit an error message and
`ERROR_TOKEN` on failure:

```cpp
case static_cast<char>(-1):
    if (m_stream.bad()) {
        m_err << "ERROR: I/O failure while reading input stream.\n";
        m_state = ERROR_TOKEN;
    } else {
        m_state = EOF_TOKEN;
    }
    break;
```

### `src/test/scanner_io.cpp` (new)
Regression test (ported from the `io_test` branch) verifying:
1. A good stream scans to completion (`n > 0` tokens).
2. A stream with `badbit` pre-set produces `ERROR_TOKEN` or a non-empty
error message rather than silent EOF.

### `src/test/main.cpp` + `src/test/CMakeLists.txt`
Register `tst_scanner_io` in the `FOR_EACH_ALL_TEST` macro and add
`scanner_io.cpp` to the build.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
Co-authored-by: Nikolaj Bjorner <nikolaj@cs.stanford.edu>
This commit is contained in:
Copilot 2026-07-29 14:00:42 -07:00 committed by GitHub
parent a3be01b9ca
commit 1c8b6cfdb8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 105 additions and 1 deletions

View file

@ -73,6 +73,7 @@
X(bit_blaster) \
X(var_subst) \
X(simple_parser) \
X(scanner_io) \
X(api) \
X(max_rev) \
X(scaled_min) \