Skip to content

A length holds and prints -1: index converts from a signed integer and to text as signed - #426

Merged
ASDAlexander77 merged 1 commit into
mainfrom
fix-index-signed-cast-and-print
Oct 1, 2026
Merged

ASDAlexander77 merged 1 commit into
mainfrom
fix-index-signed-cast-and-print

Conversation

@ASDAlexander77

Copy link
Copy Markdown
Owner

Follow-up to #425, which left let x = p.length; x = -1; printing 4294967295.

What was wrong

An index (a length) already compares as signed (for (let k = s.length - 1; k >= 0; k--) stops) and converts to number as signed (sitofp). Two places disagreed:

  • si32 -> index zero-extended. The cast fell through to the generic ZExtOp in castLLVMTypesLogic, so n = -1 stored 0x00000000FFFFFFFF. n == -1 was still true, since the literal was cast the same way, but const v: number = n was 4294967295. It now sign-extends.
  • index -> string printed unsigned. s.length - 3 printed 18446744073709551615 though s.length - 3 < 0 was true. It now prints -1.

Before / after (s = "ab", a = [1, 2]):

expression before after
let n = s.length; n = -1; print(n) 4294967295 -1
const v: number = n 4.29497e+009 -1
`${s.length - 3}` 18446744073709551615 -1
let w = a.length; w -= 5 18446744073709551613 -3
const b: any = n; print(b) 4294967295 -1

Trade-off: a length of 2^63 or more (2^31 on x86) would print negative. No real length gets that large.

Not changed

  • A user-declared signless i32 still prints unsigned (let i: i32 = 5; i = i - 6 prints 4294967295). u32 printing 4294967295 for 5 - 6 is correct.
  • let y = 1; y = 0.5 prints 0: integer literals are s32 by design.

Tests

  • New 00length_signed_arithmetic.ts (compile + jit): assignment, number / text / any conversion, length subtraction, --, -=, countdown loop.
  • Release suite: 3337/3337 passed (one test disabled, as before).
  • DefaultLib (main b67a213) rebuilt release/gc with this compiler: 158/158 compile, 158/158 jit.
  • Not run: Debug, other memory models, x86.

🤖 Generated with Claude Code

…d to text as signed

`let n = s.length; n = -1` printed 4294967295, and so did `n` as a number: the
si32 -> index cast fell through to the zext in castLLVMTypesLogic, so -1 became
0x00000000FFFFFFFF. It now sign-extends.

index -> string printed unsigned, while index already compares and converts to
number as signed: `s.length - 3` printed 18446744073709551615 though
`s.length - 3 < 0` was true. It now prints signed (-1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 929f010 into main Oct 1, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix-index-signed-cast-and-print branch October 1, 2026 16:40
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.

1 participant