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.
This commit is contained in:
@@ -976,7 +976,10 @@ pub fn globalInitValue(self: *Lowering, vd: *const ast.VarDecl, var_ty: TypeId)
|
||||
return switch (v.data) {
|
||||
.undef_literal => .zeroinit,
|
||||
.null_literal => .null_val,
|
||||
.int_literal => |il| .{ .int = il.value },
|
||||
.int_literal => |il| blk: {
|
||||
self.checkIntLiteralFits(il.value, var_ty, v.span);
|
||||
break :blk .{ .int = il.value };
|
||||
},
|
||||
.bool_literal => |bl| .{ .boolean = bl.value },
|
||||
// A float initializer at an integer-typed global follows the
|
||||
// implicit narrowing rule (integral folds, non-integral errors).
|
||||
|
||||
Reference in New Issue
Block a user