Treat results of methods without refinements as unconstrained in operations - #312
Merged
Merged
Conversation
…ations Fixes the crash when an invocation of a method with no refinements is an operand of a binary operation (#300). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Invocations whose target is not a variable (chained or static calls such as s.trim().length() or Math.max(a, b)) used as operands now also get an unconstrained fresh variable instead of `true`, which crashed Z3 with a BoolExpr/ArithExpr cast. Methods declared in interfaces no longer crash with a ClassCastException when looking up the declaring type. Add negative tests mirroring the positive ones, including branch conditions over unknown method results and typestate preservation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Collaborator
Author
|
Review of the fix, plus a follow-up commit (b7ad615). Checked
Problems found and fixed
Tests (positive and negative now mirror each other)
On the original PR code, both new Correct and Error files crash (interface cast). With the fix, 🤖 Generated with Claude Code |
rcosta358
approved these changes
Oct 1, 2026
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.
When an invocation of a method with no refinements (e.g.
s.length(),s.equals(..),list.size()) was an operand of a comparison or boolean operator,OperationsCheckerlooked up theRefinedFunction, gotnull, and crashed with an NPE, even in programs with no refinements at all.Now, in both
getOperationRefinements(invocation branch) andgetOperationRefinementFromExternalLib, a missing function yields a fresh variable of the invocation's type with refinementtrue, so the result is treated as unconstrained instead of breaking verification.Fixes #300
Testing
CorrectUnknownMethodInComparison:if (s.length() < 3),s.equals("a") || s.equals("b"), and aforloop bounded bylist.size()(crashes without the fix).ErrorUnknownMethodInOperation:@Refinement("_ > 0") int x = s.length() + 1;is still reported as a Refinement Error (no information is assumed about the result).mvn test: 340 tests run, 0 failures, 0 errors.Correct! Passed Verification.via./liquidjava.🤖 Generated with Claude Code