Commit Graph

35347 Commits

Author SHA1 Message Date
8a809099b0 update CLAUDE.md 2026-03-09 10:31:44 +00:00
3d5ac825cd sema: port decl_literal, inline call ret_ty, CG builtin resolution (num_passing=4)
- Extend ret_ty_body pre-resolution from >2 to >1 instructions,
  removing the special-case 2-inst handler in analyzeFuncBodyAndRecord.
  All multi-instruction return type bodies now use analyzeBodyInner.

- Generalize builtin_value handler with name table for all 12 types.

- Port zirDeclLiteralComptime for resolving decl_literal ZIR.
  Namespace/nav resolution for builtin types is UNIMPLEMENTED.

- Remove hardcoded strcmp dispatch in resolveCgBuiltinField — CG
  builtin fields are resolved via normal ZIR evaluation path.

- Add param→arg bindings to inst_map BEFORE analyzing ret_ty body
  in semaAnalyzeCall, so @TypeOf(a) etc. can resolve param references
  (ported from Sema.zig:7393).

- Replace all silent VOID_VALUE returns for compile-error paths
  with SEMA_FAIL macro; replace unimplemented paths with UNIMPLEMENTED.

- Add export_fn_bitcast and xor_const sema tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:31:40 +00:00
72706fb3a8 sema: port ptr_type, optional_type, builtin_value for num_passing=4
Add zirPtrType handler for comptime blocks using resolveInst-based
element type resolution (unlike resolveZirPtrTypeInst which uses ZIR).

Add optional_type handler for comptime blocks.

Generalize builtin_value handler with name table mapping all 12 type
kinds, and call ensureNavValUpToDate for unresolved navs.

Fix resolveStructFieldInitsC to skip pre-interned default values
(void, true, false, etc.) instead of crashing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:53:34 +00:00
c59d8cec39 sema: port CG builtin field handlers and @hasDecl for num_passing=1
Port resolveCgBuiltinField handlers for all CG builtin fields accessed
during start.zig comptime evaluation: output_mode, mode, unwind_tables,
wasi_exec_model, code_model, abi, and boolean fields (link_libc,
link_libcpp, single_threaded, strip_debug_info, etc.).

Port zirHasDecl (@hasDecl builtin) which resolves the container type's
namespace and looks up the decl name from the ZIR STR instruction.

Fix comptimeFieldCall arg body resolution, std_file_idx ordering,
nav name string table lookup, and resolveEnumFieldInBuiltin.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 17:39:52 +00:00
57e51b1218 sema: add UNIMPLEMENTED to all remaining silent passthroughs
Comprehensive audit found 32 silent passthroughs where unimplemented code
paths returned default values (VOID_TYPE, VOID_VALUE, TYPE_NONE, 0, etc.)
instead of crashing. Every one now calls UNIMPLEMENTED() so failures are
caught immediately rather than propagating corrupt state.

Key changes:
- semaTypeOf: crash on unhandled AIR tags instead of returning TYPE_NONE
- semaCoerce/resolvePeerTypes: crash on unhandled type combinations
- ptrChildType: crash on non-pointer types
- resolveZirTypeInst/resolveZirRefValue: crash on unhandled ZIR tags
- resolveEnumDeclFromZir: crash on unresolvable field values
- resolveStructFieldTypesC/InitsC: crash on capacity limits (>64/>32 fields)
- registerStructTypeFromZir: crash on >4 fields, inst-ref types, overflow
- resolveUnionFullyC: crash on >256 fields, tag enum overflow
- semaAnalyzeCall: crash on call/deferred body table overflow (>16)
- analyzeFuncBodyAndRecord: crash on non-C calling conventions,
  unhandled 2-inst ret type
- semaResolveSwitchComptime: crash when no case matches and no else
- zirBitSizeOf: crash on unrecognized types (arrays, structs, etc.)
- evalCrossModuleDeclValue: crash on body-completed-without-break
- ZIR_INST_STR: crash on strings >= 256 bytes
- zirEnumFromInt: crash on runtime dest type
- zirTypeofLog2IntType: crash on non-integer operand
- isComparableType: crash on ordering comparison (eq_only=false)
- getParamBody: crash on unexpected ZIR tag
- resolveZirPtrTypeInst: crash on align/addrspace/bit_range

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 15:18:37 +00:00
d676b153a3 sema: remove has_compile_errors; crash immediately on all unimplemented paths
Replace all 42 SET_ERROR/has_compile_errors patterns with UNIMPLEMENTED(),
which calls fprintf+exit(1) and uses while(1) to satisfy TCC's control-flow
analysis (TCC does not recognize exit() as noreturn).

Remove both bail-out checks on has_compile_errors. Since zig0 only processes
valid, compiling Zig code, any previously-silent error path is a bug in the
C implementation and should crash immediately rather than propagate corrupt
state.

Add UNIMPLEMENTED to 9 silent void returns identified as unimplemented paths:
zirBitcast, zirAsNode, semaAnalyzeCall (x2), @This fallback, zirRetType,
zirElemType, zirRef, zirOptionalPayload.

num_passing stays at 0 until zirFieldValComptime is implemented for the
builtin zig_backend field, which every corpus file exercises.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 15:00:14 +00:00
5beb92687b sema: replace silent fallbacks with UNIMPLEMENTED crashes
Instead of returning void values for unimplemented code paths (which
hides bugs), crash immediately with file/line info. This is simpler
than SET_ERROR + has_compile_errors propagation and makes missing
functionality immediately visible.

num_passing reduced to 0: zirFieldValComptime crashes on builtin
module's zig_backend field, which is hit by every corpus file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 14:37:17 +00:00
1f40a421e9 sema: add remaining error markers for exact shifts and block_comptime
- zirShl SHR_EXACT: extend exact shift overflow check to also cover
  SHR_EXACT (shift right must not lose non-zero bits)
  (Sema.zig zirShr exact validation)
- zirBlockComptime: when body completes without break, set
  has_compile_errors and map to void instead of leaving unmapped.
  Ported from Sema.zig block_comptime semantics (break required).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 11:04:36 +00:00
c1a5789909 sema: add error marker for zirIsNonErr type validation
zirIsNonErr: validate that operand is error union type before emitting
AIR_INST_IS_NON_ERR. Ported from Sema.zig zirIsNonErr line 18294
(checkErrorType: "expected error union type").

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 11:00:47 +00:00
7ac878f4d5 sema: add more error markers for type validation in sema.c
- zirBitcast: validate source operand type is not comptime-only,
  void, or noreturn (Sema.zig lines 9958-10010)
- zirShl SHL_EXACT: error when comptime shift overflows
  (Sema.zig lines 13943-13978: "exact shift left overflowed")

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:57:36 +00:00
e356f65e0d sema: add type validation helpers and more error markers
Add isNumericType/isComparableType helpers for type validation, and
use them in arithmetic and comparison operations:

New helpers:
- isNumericType: checks if type is int or float (for arithmetic ops)
- isComparableType: checks if type supports comparison operators
  (isSelfComparable equivalent from Sema.zig line 16620)

Error markers added:
- analyzeArithmetic emit_runtime: validate peer type is numeric
  (Sema.zig checkArithmeticOp)
- zirCmp runtime: validate peer type is comparable
  (Sema.zig analyzeCmp line 16620)
- zirCmpEq runtime: validate peer type is comparable for ==, !=
- zirShl: for SHL_EXACT comptime, error if non-zero bits shifted out
  (Sema.zig lines 13943-13978: "exact shift left overflowed")

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:56:20 +00:00
d46c3a4c0c sema: add error markers for type validation in arithmetic/unary functions
Continue adding sema->has_compile_errors = true for invalid type paths:

- analyzeBitNot: validate runtime (non-IP) operand is int/bool
  (Sema.zig zirBitNot line 14261)
- zirBoolNot: validate operand is bool type for runtime path
  (Sema.zig zirBoolNot lines 18050-18055)
- zirNegateWrap: validate operand is int/float type
  (Sema.zig zirNegateWrap lines 15006-15009)
- zirAbs: validate operand is numeric type for runtime path
  (Sema.zig zirAbs lines 20288-20296)
- zirMinMax: validate peer type is numeric for runtime path
  (Sema.zig analyzeMinMax line 24684: checkNumericType)
- zirRetNode: error if fn_ret_ty == TYPE_NONE (unresolved return type)
  (Sema.zig zirRetNode: fn_ret_ty must be known before coercion)
- zirIsNonNull: validate operand is optional/nullable type
  (Sema.zig zirIsNonNull line 18247: checkNullableType)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:51:33 +00:00
36327d4b35 sema: add error markers for more unimplemented paths
Continue adding sema->has_compile_errors = true for silent failures:

- zirReifyComptime: error for TypeInfo variants other than .int
  (Sema.zig zirReify lines 20430-20955 handles 15+ variants;
   C only handles .int)
- zirFieldPtr: error when struct type unresolvable or field not found
  (Sema.zig fieldPtr: field lookup failure is a compile error)
- zirErrUnionPayload: change silent void to error when operand is
  not error union type (Sema.zig lines 8645-8648)
- zirErrUnionCode: same validation (Sema.zig lines 8794-8797)
- zirOptionalPayload: error when comptime operand type is not optional
  (Sema.zig lines 8587-8608: failWithExpectedOptionalType)
- zirBitSizeOf: error for fn/noreturn/undefined types
  (Sema.zig lines 16765-16771: "no size available for type")
- zirAlloc: error when variable type doesn't resolve to IP value
  (Sema.zig zirAlloc: type must be resolvable at comptime)
- zirIntFromEnum: error when runtime operand is not enum/union type
  (Sema.zig lines 8373-8393)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:44:44 +00:00
38784a07fd sema: add more error markers for unimplemented/invalid code paths
Continue adding sema->has_compile_errors = true for paths where
C silently returns wrong values:

- zirBitSizeOf: error for fn/noreturn/undefined types
  (Sema.zig lines 16765-16771: "no size available for type")
- zirOptionalPayload: error when comptime operand is not optional type
  (Sema.zig lines 8587-8608: failWithExpectedOptionalType)
- zirErrUnionPayload: error when operand is not error union type
  (Sema.zig lines 8645-8648)
- zirErrUnionCode: same validation
  (Sema.zig lines 8794-8797)
- zirIntFromEnum: error when runtime operand is not enum/union type
  (Sema.zig lines 8373-8393)
- analyzeTyOpCast: validate src/dst are integer types for
  AIR_INST_INTCAST and AIR_INST_TRUNC (Sema.zig line 9834);
  keep same-type elision only for TRUNC (not INTCAST)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:40:03 +00:00
41f740aa44 sema: add error markers for unimplemented/wrong code paths
Systematically add sema->has_compile_errors = true for paths where
the C port either silently returns wrong values or is unimplemented
for valid Zig inputs. This makes failures explicit rather than
producing mysterious wrong AIR/IP output.

Changes:
- zirRetImplicit: error if function has non-void return type
  (Sema.zig lines 18700-18710)
- zirDiv: error on signed integer with plain / operator
  (Sema.zig lines 15129-15135: must use @divTrunc/@divFloor/@divExact)
- zirByteSwap: error if operand is not integer type; error if
  bits % 8 != 0 (Sema.zig lines 22956-22964)
- analyzeBitNot: error if operand is not int or bool type
  (Sema.zig line 14261)
- zirBitReverse: error if operand is not integer type
  (Sema.zig line 22980)
- zirBitCount: error if operand is not integer type
  (Sema.zig line 22905)
- zirBitwise: error if peer type is not int/bool
  (Sema.zig lines 14218-14222)
- zirBitcast: error for comptime-only or void dest types
  (Sema.zig lines 9894-9956)
- zirNegate: error on unsigned integer type
  (Sema.zig lines 14973-14978)
- zirFloatCast: error if src/dest is not a float type
  (Sema.zig lines 10046-10065)
- zirRef: error for runtime ref path (not yet implemented)
  (Sema.zig analyzeRef)
- zirLoad: error for comptime load from comptime-known pointer
  (Sema.zig analyzeLoad lines 31443-31447)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:34:22 +00:00
857936c55d sema: port zirIntFromEnum, zirEnumFromInt handlers
Add handlers for @intFromEnum and @enumFromInt:

zirIntFromEnum: if operand is a comptime enum_tag IP entry, returns
the underlying int_val directly. Runtime fallback: bitcast to
operand type.

zirEnumFromInt: if operand is a comptime int and destination is an
enum type, creates an enum_tag IP entry. Runtime fallback: bitcast
to dest enum type.

Ported from Sema.zig zirIntFromEnum and zirEnumFromInt.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:06:55 +00:00
d2571f806a sema: port zirErrUnionPayload, zirErrUnionCode handlers
Add runtime handlers for error union unwrapping instructions:
- ZIR_INST_ERR_UNION_PAYLOAD_UNSAFE/PTR → AIR_INST_UNWRAP_ERRUNION_PAYLOAD
- ZIR_INST_ERR_UNION_CODE/PTR → AIR_INST_UNWRAP_ERRUNION_ERR

Both extract the error union's payload or error set type and emit
the corresponding AIR instruction. Previously falling through to
default (void mapping).

Add UNWRAP_ERRUNION_* tags to semaTypeOf ty_op group.

Ported from Sema.zig zirErrUnionPayload → analyzeErrUnionPayload
and zirErrUnionCode.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:03:24 +00:00
88a5dc4873 sema: port zirIsNonNull, zirIsNonErr handlers
Add handlers for ZIR instructions that check if optional/error union
values are non-null/non-error:
- ZIR_INST_IS_NON_NULL / IS_NON_NULL_PTR → AIR_INST_IS_NON_NULL
- ZIR_INST_IS_NON_ERR / IS_NON_ERR_PTR / RET_IS_NON_ERR → AIR_INST_IS_NON_ERR

zirIsNonNull also folds at comptime: opt_payload → true, null → false.

Add AIR_INST_IS_NON_NULL/PTR/ERR/ERR_PTR to semaTypeOf returning bool.

Ported from Sema.zig zirIsNonNull → analyzeIsNull(invert=true) and
zirIsNonErr.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 10:00:37 +00:00
af9f80f2f7 sema: add validate-only no-op handlers for array/error union ZIR insts
Add no-op instMapPut handlers (mapped to IP_INDEX_VOID_VALUE) for
validation-only instructions that produce no meaningful value:
- ZIR_INST_VALIDATE_ARRAY_INIT_TY/RESULT_TY/REF_TY
- ZIR_INST_VALIDATE_DESTRUCTURE
- ZIR_INST_VALIDATE_PTR_ARRAY_INIT
- ZIR_INST_ENSURE_RESULT_NON_ERROR
- ZIR_INST_ENSURE_ERR_UNION_PAYLOAD_VOID

These were previously falling through to the default case (void mapping)
and are now explicitly handled as no-ops.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:57:04 +00:00
8cdc8667f4 sema: port zirBitReverse (@bitReverse)
Add handler for ZIR_INST_BIT_REVERSE which was previously falling
through to default void mapping.

Comptime folding: reverses each bit in the 128-bit representation
of the integer value. Runtime fallback: emits AIR_INST_BIT_REVERSE.

Ported from Sema.zig zirBitReverse → arith.bitReverse.
Also adds AIR_INST_BIT_REVERSE to semaTypeOf ty_op group.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:47:12 +00:00
d4636dc6cc sema: port zirDivTrunc, zirDivFloor, zirDivExact, zirMod, zirRem, zirModRem
Add handlers for the remaining division/modulo ZIR instructions that
were previously falling through to the default void mapping.

Each function handles:
- Comptime integer folding with proper sign-magnitude arithmetic
- Runtime fallback via the corresponding AIR instruction

zirDivTrunc: truncation division (rounds toward zero)
zirDivFloor: floor division (rounds toward negative infinity)
zirDivExact: exact division (same as trunc; assumes no remainder)
zirMod: @mod — result has sign of denominator
zirRem: @rem — result has sign of numerator
zirModRem: plain '%' operator (delegates to zirRem)

Ported from src/Sema.zig zirDivTrunc/zirDivFloor/zirDivExact/
zirMod/zirRem/zirModRem.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:44:18 +00:00
2f413803c6 sema: implement zirCoercePtrElemTy coercion for .one pointer types
Previously zirCoercePtrElemTy was a no-op (returned value unchanged).
Now it resolves the pointer type from the LHS, extracts the element
type, and coerces the RHS value to that element type.

Handles the .one pointer case from Sema.zig: if the element type is
known and is not anyopaque/void, coerce the value. Preserves no-op
behavior for other pointer sizes or unresolvable types.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:41:51 +00:00
607f7093cd sema: add runtime path to zirOptionalPayload
Previously, zirOptionalPayload only handled comptime optional
unwrapping. Runtime optional values (AIR instructions) returned
void instead of emitting proper AIR code.

Add runtime path: if operand is a runtime AIR instruction with
optional type, get the payload child type and emit
AIR_INST_OPTIONAL_PAYLOAD with ty_op layout.

Also add AIR_INST_OPTIONAL_PAYLOAD to semaTypeOf ty_op group.

Ported from Sema.zig zirOptionalPayload runtime path.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:39:58 +00:00
0e855d5c5e sema: add comptime_int → bool coercion in semaCoerce
When coercing comptime_int to bool, produce the correct bool constant
(IP_INDEX_BOOL_TRUE/FALSE) instead of trying to create an IP_KEY_INT
entry with bool type (which wouldn't match the pre-interned bool constants).

Ported from Sema.zig coerce comptime_int → bool path.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:33:58 +00:00
5bfb1a9a7e sema: fix zirBitSizeOf for pointer types
Pointer types (*T) now return 32 bits (wasm32-wasi target pointer
size), matching Sema.zig bitSizeSema → ptrBitWidth.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:32:37 +00:00
be87644337 sema: fix zirBitSizeOf for pointer-sized and C integer types
Add bit size computation for:
- usize/isize: 32 bits (wasm32-wasi target pointer size)
- c_char: 8 bits
- c_short/c_ushort: 16 bits
- c_int/c_uint: 32 bits
- c_long/c_ulong: 32 bits (ILP32 on wasm32-wasi)
- c_longlong/c_ulonglong: 64 bits

Ported from Sema.zig zirBitSizeOf → bitSizeSema → intInfo for
simple integer types.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:30:43 +00:00
5715f3bd90 sema: add comptime float folding to zirCmp and zirCmpEq
When both operands are comptime-known floats (IP_KEY_FLOAT),
comparison operations now fold to bool constants at compile time.

- zirCmp: adds float fold before integer fold for LT/LTE/GT/GTE
- zirCmpEq: adds float fold before integer fold for EQ/NEQ

Ported from Sema.zig cmpNumeric → compareScalars for comptime floats.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:29:14 +00:00
cd08f9002c sema: add post-coercion float fold in analyzeArithmetic
Fixes a case where comptime_int + concrete_float would not fold at
comptime: after coercion, both become float IP entries, but the
pre-coercion float check had already passed without folding.

Added a second float fold check after resolvePeerTypes+coerce, so
mixed comptime_int/float operations fold correctly.

Ported from Sema.zig analyzeArithmetic which calls resolveValue on
the coerced operands.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:26:34 +00:00
4e623e1110 sema: add comptime float folding to zirMinMax
When both @min/@max operands are comptime-known floats (IP_KEY_FLOAT),
fold the result at compile time. Result type is the wider of the two
float types, or comptime_float if both are comptime_float.

Ported from Sema.zig analyzeMinMax → Value.numberMin/Max.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:24:32 +00:00
2f1303d0db sema: add comptime float folding to zirDiv
When both operands are comptime-known float values (IP_KEY_FLOAT),
compute the division result at compile time and return the folded
float value. Matches Sema.zig zirDiv → arith.div() for comptime
float operands.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:19:27 +00:00
9487bd9acf sema: add comptime float folding to analyzeArithmetic
When both operands are comptime-known floats (IP_KEY_FLOAT entries,
including comptime_float and concrete float types), fold the result
at comptime instead of emitting a runtime AIR instruction.

Ported from Sema.zig analyzeArithmetic: resolveValue(casted_lhs/rhs)
path which evaluates comptime values via arith.add/sub/mul.

Handles ADD, SUB, MUL variants (including wrap/sat) for both
comptime_float × comptime_float and concrete float × float. Result
type is the wider of the two float types.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:18:22 +00:00
fad25d34f9 sema: fix semaCoerce comptime_int → float coercion
When semaCoerce encounters comptime_int → concrete float (or
comptime_float), it was incorrectly calling semaCoerceIntRef which
produces an IP_KEY_INT entry with a float type — wrong.

Fix by detecting the float target first: convert the integer value
to a double and intern an IP_KEY_FLOAT entry. This matches Sema.zig
coerce comptime_int → float path.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:15:02 +00:00
247b9a03e4 sema: fix resolvePeerTypes for concrete float types
When both operands are concrete float types (e.g. f32 + f64),
resolvePeerTypes returned the lhs type regardless of width.
Ported from Sema.zig peer_resolve_float strategy: return the
wider float type.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:13:42 +00:00
3fadb3583e sema: fix comptime_float handling in zirNegate, zirNegateWrap, zirAbs
zirNegate and zirNegateWrap: extend the float detection to include
IP_INDEX_COMPTIME_FLOAT_TYPE. Previously floatBits() returned 0 for
comptime_float, causing negate to fall through to integer path.
This fixes -(comptime_float) and -(comptime_float) wrap.

zirAbs: similarly extend float check to include comptime_float so
@abs on comptime_float values is properly folded at comptime.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:12:17 +00:00
b537605009 sema: fix zirCmpEq equality check to include sign for comptime ints
The comptime equality check compared only lo/hi magnitude fields,
ignoring is_negative. This meant (-5) == 5 would return true.

Fix by also checking lhs_neg == rhs_neg. Zero is never negative
(internComptimeInt already clears neg for zero values), so this
handles the -0 == 0 edge case correctly.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:09:35 +00:00
5e1ea76798 sema: fix zirCmp signed comparison for comptime integers
The comptime folding path in zirCmp used unsigned comparison of
the magnitude fields (lo/hi), ignoring the is_negative sign flag.
This gave wrong results for mixed-sign comparisons like (-5) < 3.

Replace with a proper signed 128-bit comparison that:
- If signs differ: negative < positive
- Both non-negative: compare magnitudes in ascending order
- Both negative: compare magnitudes in descending order (larger mag = smaller value)

Also derive equality separately for LTE/GTE cases.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:08:08 +00:00
2351a2217b sema: fix zirAbs comptime_int folding and typed signed int folding
zirAbs now folds @abs for comptime_int operands: absolute value is
simply clearing the is_negative flag. This matches Sema.zig which
treats comptime_int like float/comptime_float (result_ty = operand_ty)
and calls maybeConstantUnaryMath(Value.abs).

Also fold @abs for comptime-known typed signed integers: since the
result type is already unsigned, we just intern the magnitude (lo/hi)
with the unsigned result type and is_negative=false.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:06:32 +00:00
b4da5d7bd5 sema: fix zirBoolBr comptime fold, zirTypeofBuiltin want_safety
zirBoolBr: after analyzing the RHS body, if the result is
comptime-known and equals the short-circuit value (true for or,
false for and), fold the whole expression to the comptime result.
This matches Sema.zig lines 18167-18173.

zirTypeofBuiltin: set want_safety=false on the typeof block, matching
Sema.zig line 17941 which explicitly disables safety in typeof blocks.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 09:02:47 +00:00
7f478b70ea sema: fix sign-magnitude arithmetic for comptime integers
Several comptime folding paths in sema.c ignored the is_negative flag
of sign-magnitude InternPool integers:

- internComptimeInt: add `neg` parameter (was hardcoded false).
- analyzeArithmetic: implement sign-aware add/sub/mul via addSignedMag128
  helper. add(a,b) handles mixed signs by subtracting smaller magnitude;
  sub(a,b) = add(a,-b); mul result_neg = lhs_neg XOR rhs_neg.
- zirDiv: pass correct sign to result (lhs_neg != rhs_neg).
- zirShl/zirShr: preserve lhs sign through comptime shift.
- zirMinMax: use isComptimeIntWide (128-bit) instead of isComptimeInt
  (64-bit) and implement full 128-bit signed comparison.
- semaTypeOf: add DIV_FLOOR, DIV_EXACT, DIV_FLOAT_OPTIMIZED, MOD, REM
  to the bin_op type-from-lhs group.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:58:42 +00:00
039a00606b sema: fix 128-bit byteswap logic and cppcheck false condition
Simplify the 128-bit case in zirByteSwap comptime folding:
- r_lo byte b ← val_hi byte (7-b)
- r_hi byte b ← val_lo byte (7-b)
Previous code had a dead `src < 8` check (always false).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:13:31 +00:00
326d51e30e sema: fix semaCoerce comptime_float → integer coercion
Add the float-to-integer coercion path: convert the float value to an
integer (truncating toward zero) and intern it with the target type.
Previously, comptime_float coercion to integer types was silently
ignored, returning the original float ref unchanged.

Also restructure the comptime_float case to explicitly separate
float→float from float→int paths.

Matches src/Sema.zig coerce: getCoerced(val, dst_ty) for float→int.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:08:28 +00:00
8538d0b27b sema: add comptime integer division folding to zirDiv
For comptime-known integer operands (64-bit case), compute the quotient
at comptime instead of emitting AIR. Matches src/Sema.zig zirDiv: arith.div
for comptime-known values.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:07:35 +00:00
d0e90b94e9 sema: fix zirBitCount comptime folding to use 128-bit wide values
Replace 64-bit isComptimeInt with 128-bit isComptimeIntWide for CLZ,
CTZ, and POPCOUNT comptime evaluation. Correctly handles integer types
wider than 64 bits (e.g. u128, i128).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:07:02 +00:00
2d62c61b70 sema: add comptime float folding to zirNegate
For comptime-known float operands, compute -val at comptime instead of
emitting AIR_INST_NEG. Matches src/Sema.zig zirNegate: arith.negateFloat
for comptime values, preserving negative zero semantics.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:06:09 +00:00
427b428db8 sema: add comptime folding to zirAbs for float operands
For comptime-known float operands, compute abs(val) at comptime
instead of emitting AIR. Matches src/Sema.zig zirAbs: maybeConstantUnaryMath
with Value.abs. Also extends to comptime_float type.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:05:34 +00:00
1ccc0e54d9 sema: add comptime folding to zirByteSwap
For comptime-known integer operands with bit-aligned widths, compute
the byte-swapped value at comptime rather than emitting AIR.
Matches src/Sema.zig zirByteSwap: arith.byteSwap() comptime path.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:05:02 +00:00
1a1a4d3d25 sema: fix zirNegateWrap float zero creation
For float operands, create IP_KEY_FLOAT(0.0) instead of IP_KEY_INT(0).
The previous code created an int zero with a float type, which is an
invalid IP entry. Matches src/Sema.zig zirNegateWrap: pt.intValue()
returns the appropriate zero for the scalar type.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:04:22 +00:00
15f5284082 sema: fix zirBitwise to coerce before comptime folding
Match upstream Sema.zig zirBitwise structure: resolve peer types and
coerce operands FIRST, then attempt comptime folding on the coerced
values. This ensures typed IP entries (e.g. u16(3)) are created as
side effects of coercion, matching Zig's IP entry sequence.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 08:03:52 +00:00
51cbaabe22 sema: port zirLoop from upstream Sema.zig
Implement runtime while/for loop handling:
- Reserve block_inst (outer) + loop_inst (inner) in advance
- Analyze loop body in loop_block
- If body ends noreturn: copy instructions to child_block (no repeat)
- Otherwise: add repeat instruction, set up loop_inst body in air_extra
- Resolve outer block via label merges (handles break-from-loop)

Matches src/Sema.zig zirLoop decomposition.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 07:45:22 +00:00
39b2e51a28 sema: fix resolveFuncRetType for single-instruction type refs
Use resolveZirTypeRef instead of returning void for instruction refs
in the single-instruction return type body case. This handles ptr_type,
int_type, array_type, etc. Matches upstream's resolveType call in zirFunc.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-07 07:39:33 +00:00