Skip to content

Fix ICE on pattern types over wide pointers under -Z valid-value-checks - #4856

Merged
feliperodri merged 3 commits into
model-checking:mainfrom
Tianshu-Huang:fix-4829-fat-pointer-pattern
Sep 30, 2026
Merged

feliperodri merged 3 commits into
model-checking:mainfrom
Tianshu-Huang:fix-4829-fat-pointer-pattern

Conversation

@Tianshu-Huang

@Tianshu-Huang Tianshu-Huang commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

ty_validity_per_offset asserted that a pattern type has a Scalar layout. NonNull<[u8]>'s field is pattern_type!(*const [u8] is !null), a wide pointer with a ScalarPair layout, and every allocation reaches it, so -Z valid-value-checks ICE'd on any program using Box/Vec/String.

Accept ScalarPair alongside Scalar. try_from_ty already takes the first scalar's valid_range for a pair, which is the data pointer's !null, the same way &[u8] is checked. Any other layout is reported as unsupported instead of asserted on.

The regression test uses the issue's reproducer: Box::new now verifies, and a second harness that transmutes a null data pointer into NonNull<[u8]> fails with Invalid value of type NonNull<[u8]>, so the check is enforced rather than skipped.

Resolves #4829

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

@Tianshu-Huang
Tianshu-Huang requested review from a team as code owners September 24, 2026 18:35
@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 24, 2026
@feliperodri
feliperodri requested a balanced review from Copilot September 25, 2026 17:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Existing comments still incorrectly state that all pattern types have scalar ABIs.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 Low severity

Open (1)
What changed in this PR

Prevents -Z valid-value-checks from crashing on wide-pointer pattern types.

Changes:

  • Returns an unsupported-check error for non-scalar pattern types.
  • Adds an allocation regression test and expected diagnostic.
File Description
kani-compiler/​src/​kani_middle/​transform/​check_values.rs Replaces the scalar-ABI assertion with graceful rejection.
tests/​expected/​valid-value-checks/​fat_pointer_pattern.rs Adds the allocation regression case.
tests/​expected/​valid-value-checks/​fat_pointer_pattern.expected Captures the expected unsupported-check result.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread kani-compiler/src/kani_middle/transform/check_values.rs

@feliperodri feliperodri left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for picking this up. The crash is gone, but the fix trades it for a spurious failure. Every allocation reaches NonNull<[u8]>, so reporting it as unsupported makes every allocating program fail verification under -Z valid-value-checks. The new test shows it: a correct Box program is expected to FAIL. The flag stays unusable on real code, which was #4829's impact.

The pass already knows how to check wide pointers. try_from_ty reads the first scalar of a ScalarPair, which is the data pointer and its valid range, and that's how &[u8] and *const [u8] are handled today. The !null of *const [u8] is !null is exactly that range, so accepting ScalarPair here is enough:

-        if !matches!(layout.value_repr, ValueRepr::Scalar(..)) {
+        if !matches!(layout.value_repr, ValueRepr::Scalar(..) | ValueRepr::ScalarPair { .. }) {

I tried it: Box::new, Vec::push, and a non-null NonNull<[u8]> transmute all verify, and a transmute with a null data pointer is still caught as Undefined Behavior: Invalid value of type NonNull<[u8]>. The other 10 tests using -Z valid-value-checks are unchanged.

What would flip this to approval: that change, with fat_pointer_pattern expecting SUCCESSFUL, plus a harness with a null data pointer that must FAIL, so the test shows the requirement is enforced and not skipped. Box<dyn Debug> and Rc<str> then stop at other, pre-existing unsupported constructs (fmt::rt, copy_nonoverlapping on *const u8). Those are separate issues, not this PR's.

Comment thread kani-compiler/src/kani_middle/transform/check_values.rs Outdated
Comment thread tests/expected/valid-value-checks/fat_pointer_pattern.expected Outdated
Comment thread tests/expected/valid-value-checks/fat_pointer_pattern.rs

@feliperodri feliperodri left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the quick turnaround — this addresses everything from my earlier review. Accepting ScalarPair lets allocating code verify under -Z valid-value-checks. null_data_pointer shows the !null requirement is enforced rather than skipped. Unknown layouts now return an unsupported-check error instead of asserting, so the pass can't ICE here. The note on why assert_eq!(nn.len(), 3) is there is helpful too.

I checked it locally, merged with current main. All 10 valid-value-checks tests pass. Vec::push and NonNull::from(&a[..]) verify, and a NonNull<[u8]> whose data pointer is kani::any() is correctly reported as invalid.

One non-blocking note: only the first scalar of the pair is checked. For NonNull<dyn Trait> that means a null vtable isn't caught, the same as for &dyn Trait today. That gap is #3738, not this PR.

@feliperodri
feliperodri added this pull request to the merge queue Sep 30, 2026
@feliperodri feliperodri removed their assignment Sep 30, 2026
Merged via the queue into model-checking:main with commit 16722a9 Sep 30, 2026
33 of 34 checks passed
srivatsansamraj pushed a commit to srivatsansamraj/kani that referenced this pull request Sep 30, 2026
…del-checking#4923)

Pass `--harness-timeout 5m` to
`script-based-pre/cargo_autoharness_fmt_impls`, as the other autoharness
tests (`bounded`, `bounds`, `byte_str`, `c_str`, `formatter`, `wtf8`)
already do.

**Why.** On the macOS x86_64 runners (`regression (macos-15-intel)`),
the `LowerExp`, `UpperExp` and `Pointer` harnesses of this test take
40–60 s, right at `kani autoharness`'s default `--harness-timeout` of 60
s. When one of them times out, CBMC reports `CBMC timed out` instead of
the expected failure, the test's `Failed Checks: "lower exp"` / `"upper
exp"` / `"pointer"` line is missing, and the test fails. The same
harnesses take about 10 s on Linux.

**Evidence.** I went through the logs of the `regression
(macos-15-intel)` jobs between 2026-09-28 and 2026-09-30. 33 of them
failed. This test failed in all 33, with 1–3 of those three harnesses
timing out each time, and in 32 of them it was the only failing test.
The one exception, model-checking#4903's merge-queue push run, also had
`cargo_autoharness_wtf8`'s `len` harness time out, at 5 m. On main
pushes alone, the job failed 7 times out of 12 on 2026-09-30. The
failures are independent of the changes under test:

- Today's automated toolchain upgrade, model-checking#4917: [run
36663872235](https://github.com/model-checking/kani/actions/runs/36663872235/job/109726991201)
(`LowExp`, `UpExp`, `Ptr` timed out; every other regression job passed)
- `main` pushes:
[36654469481](https://github.com/model-checking/kani/actions/runs/36654469481/job/109695682794),
[36656240395](https://github.com/model-checking/kani/actions/runs/36656240395/job/109701095388),
[36657849257](https://github.com/model-checking/kani/actions/runs/36657849257/job/109705923680),
[36659060566](https://github.com/model-checking/kani/actions/runs/36659060566/job/109709545862),
[36670355214](https://github.com/model-checking/kani/actions/runs/36670355214/job/109743820142),
[36674524840](https://github.com/model-checking/kani/actions/runs/36674524840/job/109756493668)
- Merge queue: model-checking#4895
[36650793954](https://github.com/model-checking/kani/actions/runs/36650793954/job/109684194253),
model-checking#4896
[36650908721](https://github.com/model-checking/kani/actions/runs/36650908721/job/109684568489),
model-checking#4809
[36654883143](https://github.com/model-checking/kani/actions/runs/36654883143/job/109696960300),
model-checking#4848
[36663305755](https://github.com/model-checking/kani/actions/runs/36663305755/job/109722546228),
model-checking#4903
[36667236036](https://github.com/model-checking/kani/actions/runs/36667236036/job/109734401431),
model-checking#4856
[36670723600](https://github.com/model-checking/kani/actions/runs/36670723600/job/109744937944),
model-checking#4881
[36596324505](https://github.com/model-checking/kani/actions/runs/36596324505/job/109502054372),
model-checking#4882
[36612997613](https://github.com/model-checking/kani/actions/runs/36612997613/job/109558873539)
- Pull requests: model-checking#4875
[36427316996](https://github.com/model-checking/kani/actions/runs/36427316996/job/109072277288),
model-checking#4895
[36443349794](https://github.com/model-checking/kani/actions/runs/36443349794/job/108999214513),
model-checking#4771
[36620184925](https://github.com/model-checking/kani/actions/runs/36620184925/job/109677883533)

The runner image version (`20260819.586`) was the same in passing and
failing runs.

**Manual testing.** Locally the three harnesses take about 10 s each.
Running the test with `--harness-timeout 3s` reproduces the CI failure
exactly: the same three harnesses time out, their `Failed Checks` lines
are missing, and the summary still reports 9 failures. With this change,
`cargo run -p compiletest -- --suite script-based-pre --mode exec
cargo_autoharness_fmt_impls` passes.

If the macOS Intel runner gets much slower, a longer timeout alone may
not be enough; making these three harnesses cheaper would be the next
step.

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

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

panic: -Z valid-value-checks ICEs on any allocating function: fat-pointer pattern type in NonNull<[u8]>

3 participants