Skip to content

Build char literals directly instead of parsing their text - #447

Merged
CatarinaGamboa merged 1 commit into
mainfrom
fix/444-char-literals
Oct 29, 2026
Merged

CatarinaGamboa merged 1 commit into
mainfrom
fix/444-char-literals

Conversation

@CatarinaGamboa

Copy link
Copy Markdown
Collaborator

Fixes #444.

Problem

Comparing a char with a literal like '[', '{', ',', ' ' or 'Z' was rejected with Syntax Error: Invalid refinement expression. Three places (OperationsChecker operands, operator assignments, and RefinementTypeChecker#getExpressionRefinements) built a literal's predicate by parsing literal.getValue().toString(), and RJ has no char-literal token.

The literals that "passed" were also wrong, which the issue suspected:

  • '0' parsed as the int 0, not 48
  • 'a' parsed as a variable a, so it took the value of any local named a

Both are unsound. On main, ErrorCharLiteralComparisons below verifies with no errors.

Fix

Predicate.createLit(Object, CtElement) wraps the value with the existing StaticConstants.asLiteralPredicate, the same path resolved static final constants already use, so a Character becomes a LiteralChar (an int in Z3). Values it doesn't model fall back to the old parse.

Tests

  • CorrectCharLiteralComparisons: the reproducer from the issue (charAt(i) != '['), punctuation/space/uppercase/escaped comparisons, '0' == 48, 'a' with a local a in scope, and a += with a char literal
  • ErrorCharLiteralComparisons: '0' is not 0, and 'a' is not the local a = 5 (both pass silently on main)

./mvnw test: 534 tests, 0 failures.

🤖 Generated with Claude Code

Literals in operations, operator assignments and expression refinements
were turned into predicates by parsing getValue().toString(). RJ has no
char-literal syntax, so '[' or ' ' raised a syntax error, 'a' was read as
a variable named a, and '0' as the int 0. Wrap the value as an RJ literal
node instead, as StaticConstants already does for resolved constants.

Fixes #444

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@CatarinaGamboa
CatarinaGamboa merged commit 19991d3 into main Oct 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

False error: comparing with a char literal other than a lowercase letter, digit or _ ('[', 'Z', ' ') is rejected as an invalid refinement expression

1 participant