Skip to content

Autoharness: support &Wtf8 arguments under --bounded-arguments - #4809

Open
srivatsansamraj wants to merge 4 commits into
model-checking:mainfrom
srivatsansamraj:wtf8-bounded-ref
Open

srivatsansamraj wants to merge 4 commits into
model-checking:mainfrom
srivatsansamraj:wtf8-bounded-ref

Conversation

@srivatsansamraj

Copy link
Copy Markdown
Contributor

&str arguments are generated from nondeterministic harness-local storage by any_str_ref; #4804 adds &CStr and #4806 &ByteStr. &Wtf8 had no model and was skipped for a missing Arbitrary implementation: 32 functions in core on a whole-library verify-std run.

WTF-8 is a superset of UTF-8, so any_wtf8_ref is Wtf8::from_str over any_str_ref, with the string bound. Strings holding surrogate code points are not generated, since core has no WTF-8 validator to build them soundly. Eligibility and harness generation identify the type through is_wtf8, matched by name inside core::wtf8 since the type has no diagnostic item. &mut Wtf8 stays unsupported, as &mut str does. The kani crate gains #![feature(wtf8_internals)]; std does not re-export the module, so the model names the type through core.

The test follows cargo_autoharness_byte_str: reported as requiring the flag without it; with it, an unchecked index fails on the empty value, and covers show the empty, the 4-byte and a specific string are all generated.

This branch includes #4804 and #4806; only the last commit is new here.

Resolves #4808

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

`&str` arguments are generated by `any_str_ref`, which returns the longest valid-UTF-8
prefix of nondeterministic harness-local storage. `&CStr` had no such model and was
skipped for a missing Arbitrary implementation: 67 functions on a whole-library
`verify-std` run, 23 of them in `core`.

Add `any_c_str_ref` with the same discipline. The last byte of the storage is set to NUL
and `from_bytes_until_nul` returns the bytes before the first one, so the result is a
deterministic function of the nondeterministic bytes and satisfies `CStr`'s invariant by
construction: no `assume` is involved, and every C string of length `k` below the bound
arises from storage whose first NUL is at index `k`. The slice bound applies, less one
byte for the NUL.

Eligibility and harness generation both identify `CStr` through `is_c_str`, so they
cannot disagree. `&mut CStr` stays unsupported, as `&mut str` does.

The test follows `cargo_autoharness_slices`: the argument is reported as requiring the
flag without it, and with it a bounds-checked read fails on the empty string, the
no-interior-NUL invariant holds, and covers show the empty, the longest and a specific
C string are all generated.
@srivatsansamraj
srivatsansamraj requested review from a team as code owners September 18, 2026 08:56
@github-actions github-actions Bot added Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-CompilerBenchCI Tag a PR to run benchmark CI labels Sep 18, 2026
The local receiving the `any_c_str_ref` call was typed `&mut CStr`, the shape the slice
model returns, while the model returns `&CStr`; the value was then reborrowed as shared.
Codegen tolerated the mismatch, but the MIR was ill-typed. Only the slice model returns
`&mut [T]`, to serve both mutabilities; the string models return the shared reference. The
destination now follows that, and the reborrow applies to slices only.
`&[T]` and `&str` arguments are generated from nondeterministic harness-local storage
by `any_slice_ref` and `any_str_ref`, and `&CStr` by `any_c_str_ref`. `&ByteStr` had
no model and was skipped for a missing Arbitrary implementation: 104 functions on a
whole-library `verify-std` run, 88 of them in `core`.

A `ByteStr` is a `[u8]` with no further invariant, so `any_byte_str_ref` is
`ByteStr::new` over `any_slice_ref`, with the slice bound. Eligibility and harness
generation identify the type through `is_byte_str`, matched by name inside
`core::bstr` since the type has no diagnostic item. `&mut ByteStr` stays unsupported,
as `&mut str` does. The `kani` crate gains `#![feature(bstr)]`; inside `core` the
module is already present.

The test follows `cargo_autoharness_slices`: reported as requiring the flag without
it; with it, an unchecked index fails on the empty value, and covers show the empty,
the 16-byte and a specific byte string are all generated.
`&str` arguments are generated from nondeterministic harness-local storage by
`any_str_ref`, `&CStr` by `any_c_str_ref` and `&ByteStr` by `any_byte_str_ref`. `&Wtf8`
had no model and was skipped for a missing Arbitrary implementation: 32 functions in
`core` on a whole-library `verify-std` run.

WTF-8 is a superset of UTF-8, so `any_wtf8_ref` is `Wtf8::from_str` over `any_str_ref`,
with the string bound. Strings holding surrogate code points are not generated, since
`core` has no WTF-8 validator to build them soundly. Eligibility and harness generation
identify the type through `is_wtf8`, matched by name inside `core::wtf8` since the type
has no diagnostic item. `&mut Wtf8` stays unsupported, as `&mut str` does. The `kani`
crate gains `#![feature(wtf8_internals)]`; `std` does not re-export the module, so the
model names the type through `core`.

The test follows `cargo_autoharness_byte_str`: reported as requiring the flag without
it; with it, an unchecked index fails on the empty value, and covers show the empty, the
4-byte and a specific string are all generated.
@feliperodri feliperodri added this to the Autoharness milestone Sep 20, 2026
@feliperodri feliperodri added the Z-Autoharness Issue related to autoharness subcommand label Sep 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-Autoharness Issue related to autoharness subcommand Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Autoharness: support &Wtf8 arguments under --bounded-arguments

2 participants