Files
sx/examples/0174-types-int-literal-boundaries.sx
agra 67313e1dad fix(0112): out-of-range int literals error instead of silently wrapping
checkIntLiteralFits range-checks a literal against its integer target
(builtins + custom widths via intLiteralRange; width-64 types skip —
every representable literal is a legal bit pattern there) and diagnoses
with the type's range and an xx/cast hint. Wired into the .int_literal
arm (covers decls, assignments, call args, struct-literal fields),
lowerStructConstant, and globalInitValue.

A negated literal now folds to a single constant so -128 range-checks
as -128 rather than as an out-of-range +128 intermediate. An explicit
xx operand skips the check — truncation stays available on request
(cast(T) was already exempt: its value arg lowers without the target).

examples/0300-closures-lambda.sx pinned 133 wrapping to -3 through an
s3 param — the exact class this outlaws; updated to a fitting value.

Found during the fix and filed separately: issue 0113 (negated-literal
global initializers rejected as non-constant; pre-existing).

Regressions: examples/1156-diagnostics-int-literal-out-of-range.sx,
examples/0174-types-int-literal-boundaries.sx.
2026-06-10 22:28:24 +03:00

23 lines
745 B
Plaintext

// Boundary and exemption cases for the int-literal fits-check: extreme
// in-range values compile (incl. negated literals via the constant fold);
// width-64 types accept any representable literal; explicit `xx` / `cast`
// still truncate on request; literal call args check against param types.
#import "modules/std.sx";
clamp_s8 :: (v: s8) -> s8 { v }
main :: () {
a : s8 = -128;
b : s8 = 127;
c : u8 = 0;
d : u8 = 255;
e : u64 = 0x7FFFFFFFFFFFFFFF;
f : u32 = 0xFFFFFFFF;
g : s16 = -32768;
h : s8 = xx 300; // explicit truncation stays legal
i := cast(s8) 300; // cast form too
j : s8 = clamp_s8(-5);
print("{} {} {} {} {} {} {} {} {} {}\n", a, b, c, d, e, f, g, h, i, j);
}