commit 1f40a421e9ff4c246caea645f501bd1280d8f153 (tree)
parent c1a578990935ae85d566919ed19a20318cb67ebd
Author: Motiejus <motiejus@jakstys.lt>
Date: Sat, 7 Mar 2026 11:04:36 +0000
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>
Diffstat:
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/stage0/sema.c b/stage0/sema.c
@@ -2678,20 +2678,30 @@ static AirInstRef zirShl(
shr128(lhs_lo, lhs_hi, shift, &r_lo, &r_hi);
// Ported from Sema.zig zirShl lines 13943-13978:
// For shl_exact, error if non-zero bits were shifted out.
- if (air_tag == AIR_INST_SHL_EXACT
+ if ((air_tag == AIR_INST_SHL_EXACT || air_tag == AIR_INST_SHR_EXACT)
&& sema->ip->items[lhs_ty].tag == IP_KEY_INT_TYPE) {
uint16_t bits = sema->ip->items[lhs_ty].data.int_type.bits;
- // Check if shift amount >= bit width (all bits shifted out).
+ // Ported from Sema.zig zirShl/zirShr exact overflow check:
+ // Check if shift amount >= bit width.
if (shift >= bits) {
sema->has_compile_errors = true;
return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
}
- // Check if non-zero bits were shifted out (for <= 64 bit types).
if (bits <= 64 && shift > 0) {
- uint64_t lost_bits_mask = UINT64_MAX << (bits - shift);
- if (lhs_lo & lost_bits_mask) {
- sema->has_compile_errors = true;
- return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
+ if (air_tag == AIR_INST_SHL_EXACT) {
+ // Check if non-zero bits were shifted out (left).
+ uint64_t lost_bits_mask = UINT64_MAX << (bits - shift);
+ if (lhs_lo & lost_bits_mask) {
+ sema->has_compile_errors = true;
+ return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
+ }
+ } else {
+ // SHR_EXACT: check if non-zero bits shifted off right.
+ uint64_t lost_bits_mask = (UINT64_C(1) << shift) - 1;
+ if (lhs_lo & lost_bits_mask) {
+ sema->has_compile_errors = true;
+ return AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE);
+ }
}
}
}
@@ -11158,6 +11168,13 @@ static void zirBlockComptime(Sema* sema, SemaBlock* block, uint32_t inst) {
result = resolveInst(sema, operand);
}
instMapPut(&sema->inst_map, inst, result);
+ } else {
+ // Ported from Sema.zig block_comptime: body must end with break.
+ // If body completed without a break, the block is ill-formed.
+ // Map to void and propagate error so callers see the failure.
+ sema->has_compile_errors = true;
+ instMapPut(
+ &sema->inst_map, inst, AIR_REF_FROM_IP(IP_INDEX_VOID_VALUE));
}
semaBlockDeinit(&ct_block);
}