| ... | ... | @@ -1540,6 +1540,24 @@ fn resolveMaybeUndefVal( |
| 1540 | 1540 | } |
| 1541 | 1541 | } |
| 1542 | 1542 | |
| 1543 | /// Value Tag `variable` results in `null`. |
| 1544 | /// Value Tag `undef` results in the Value. |
| 1545 | /// Value Tag `generic_poison` causes `error.GenericPoison` to be returned. |
| 1546 | /// Value Tag `decl_ref` and `decl_ref_mut` or any nested such value results in `null`. |
| 1547 | fn resolveMaybeUndefValIntable( |
| 1548 | sema: *Sema, |
| 1549 | block: *Block, |
| 1550 | src: LazySrcLoc, |
| 1551 | inst: Air.Inst.Ref, |
| 1552 | ) CompileError!?Value { |
| 1553 | const val = (try sema.resolveMaybeUndefValAllowVariables(block, src, inst)) orelse return null; |
| 1554 | switch (val.tag()) { |
| 1555 | .variable, .decl_ref, .decl_ref_mut => return null, |
| 1556 | .generic_poison => return error.GenericPoison, |
| 1557 | else => return val, |
| 1558 | } |
| 1559 | } |
| 1560 | |
| 1543 | 1561 | /// Returns all Value tags including `variable` and `undef`. |
| 1544 | 1562 | fn resolveMaybeUndefValAllowVariables( |
| 1545 | 1563 | sema: *Sema, |
| ... | ... | @@ -9302,19 +9320,27 @@ fn zirBitwise( |
| 9302 | 9320 | return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) }); |
| 9303 | 9321 | } |
| 9304 | 9322 | |
| 9305 | | if (try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs)) |lhs_val| { |
| 9306 | | if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| { |
| 9307 | | const result_val = switch (air_tag) { |
| 9308 | | .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target), |
| 9309 | | .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target), |
| 9310 | | .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target), |
| 9311 | | else => unreachable, |
| 9312 | | }; |
| 9313 | | return sema.addConstant(resolved_type, result_val); |
| 9323 | const runtime_src = runtime: { |
| 9324 | // TODO: ask the linker what kind of relocations are available, and |
| 9325 | // in some cases emit a Value that means "this decl's address AND'd with this operand". |
| 9326 | if (try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs)) |lhs_val| { |
| 9327 | if (try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs)) |rhs_val| { |
| 9328 | const result_val = switch (air_tag) { |
| 9329 | .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target), |
| 9330 | .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target), |
| 9331 | .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target), |
| 9332 | else => unreachable, |
| 9333 | }; |
| 9334 | return sema.addConstant(resolved_type, result_val); |
| 9335 | } else { |
| 9336 | break :runtime rhs_src; |
| 9337 | } |
| 9338 | } else { |
| 9339 | break :runtime lhs_src; |
| 9314 | 9340 | } |
| 9315 | | } |
| 9341 | }; |
| 9316 | 9342 | |
| 9317 | | try sema.requireRuntimeBlock(block, src); |
| 9343 | try sema.requireRuntimeBlock(block, runtime_src); |
| 9318 | 9344 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); |
| 9319 | 9345 | } |
| 9320 | 9346 | |
| ... | ... | @@ -10163,8 +10189,8 @@ fn analyzeArithmetic( |
| 10163 | 10189 | |
| 10164 | 10190 | const mod = sema.mod; |
| 10165 | 10191 | const target = mod.getTarget(); |
| 10166 | | const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs); |
| 10167 | | const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs); |
| 10192 | const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs); |
| 10193 | const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs); |
| 10168 | 10194 | const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: { |
| 10169 | 10195 | switch (zir_tag) { |
| 10170 | 10196 | .add => { |