Treat null literals as carrying no information instead of failing - #311
Merged
Merged
Conversation
Refs #301: null literals and comparisons with null no longer raise "Null literals are not supported"; they produce a true predicate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Treating `x == null` / `x != null` as the constant `true` made the negated condition `false`, so else branches of `||` conditions were considered dead, `&&` else branches gained a false fact, and ternaries and boolean locals took a fixed value. A null comparison now becomes a fresh unconstrained boolean variable; other operands keep their facts. Adds ErrorNullLiterals (negative test) and extends CorrectNullLiterals. Refs #301 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Review: there was a soundness bug. A null comparison was modelled as the constant
All of these passed verification on 5bf4604. Fix (cedbdec): a comparison with Tests:
🤖 Generated with Claude Code |
CatarinaGamboa
added a commit
that referenced
this pull request
Oct 2, 2026
Review fixes for the loop-condition change (#306): - a continue reaches the for update without the rest of the body, so when the body has one, the update no longer sees the body's path conditions or assignments (`for (..; ..; use(n)) { if (n <= 0) continue; ... }` was accepted) - a loop also changes fields (through any call) and the state of objects it calls state-changing methods on; these are now havocked too, since the assumed condition could otherwise combine with their stale values (accepted programs that main rejected) - drop the null check on the condition, dead since null literals carry no information (#311) - move the i++ path-condition fix out (it is not needed for loops and is a separate pre-existing bug in if branches) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Null literals (
x = null,x == null,x != null,f(null)) no longer raiseNull literals are not supportedand stop verification of the rest of the file.In
OperationsChecker, a null literal now yieldsnew Predicate()(true), like String literals already do, and a binary operation with a null operand also yieldstrue(otherwise e.g.name == nullbecamename == trueand failed with a Z3 sort mismatch). No null reasoning is added.Fixes #301
Testing:
CorrectNullLiterals.java: null-initialised local,== null/!= nullinif,nullpassed to an unrefined method, theX s = null; try { ... } finally { if (s != null) ... }shape, plus an unrelated int refinement that still verifies.if (name == null)branch is still reported as a Refinement Error.mvn test: 339 tests, 0 failures (existingErrorEnumNullstill fails as expected).🤖 Generated with Claude Code