| ... | @@ -1540,6 +1540,24 @@ fn resolveMaybeUndefVal( | ... | @@ -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 | /// Returns all Value tags including `variable` and `undef`. | 1561 | /// Returns all Value tags including `variable` and `undef`. |
| 1544 | fn resolveMaybeUndefValAllowVariables( | 1562 | fn resolveMaybeUndefValAllowVariables( |
| 1545 | sema: *Sema, | 1563 | sema: *Sema, |
| ... | @@ -9302,19 +9320,27 @@ fn zirBitwise( | ... | @@ -9302,19 +9320,27 @@ fn zirBitwise( |
| 9302 | return sema.fail(block, src, "invalid operands to binary bitwise expression: '{s}' and '{s}'", .{ @tagName(lhs_ty.zigTypeTag()), @tagName(rhs_ty.zigTypeTag()) }); | 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| { | 9323 | const runtime_src = runtime: { |
| 9306 | if (try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs)) |rhs_val| { | 9324 | // TODO: ask the linker what kind of relocations are available, and |
| 9307 | const result_val = switch (air_tag) { | 9325 | // in some cases emit a Value that means "this decl's address AND'd with this operand". |
| 9308 | .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target), | 9326 | if (try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs)) |lhs_val| { |
| 9309 | .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target), | 9327 | if (try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs)) |rhs_val| { |
| 9310 | .xor => try lhs_val.bitwiseXor(rhs_val, resolved_type, sema.arena, target), | 9328 | const result_val = switch (air_tag) { |
| 9311 | else => unreachable, | 9329 | .bit_and => try lhs_val.bitwiseAnd(rhs_val, resolved_type, sema.arena, target), |
| 9312 | }; | 9330 | .bit_or => try lhs_val.bitwiseOr(rhs_val, resolved_type, sema.arena, target), |
| 9313 | return sema.addConstant(resolved_type, result_val); | 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 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); | 9344 | return block.addBinOp(air_tag, casted_lhs, casted_rhs); |
| 9319 | } | 9345 | } |
| 9320 | | 9346 | |
| ... | @@ -10163,8 +10189,8 @@ fn analyzeArithmetic( | ... | @@ -10163,8 +10189,8 @@ fn analyzeArithmetic( |
| 10163 | | 10189 | |
| 10164 | const mod = sema.mod; | 10190 | const mod = sema.mod; |
| 10165 | const target = mod.getTarget(); | 10191 | const target = mod.getTarget(); |
| 10166 | const maybe_lhs_val = try sema.resolveMaybeUndefVal(block, lhs_src, casted_lhs); | 10192 | const maybe_lhs_val = try sema.resolveMaybeUndefValIntable(block, lhs_src, casted_lhs); |
| 10167 | const maybe_rhs_val = try sema.resolveMaybeUndefVal(block, rhs_src, casted_rhs); | 10193 | const maybe_rhs_val = try sema.resolveMaybeUndefValIntable(block, rhs_src, casted_rhs); |
| 10168 | const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: { | 10194 | const rs: struct { src: LazySrcLoc, air_tag: Air.Inst.Tag } = rs: { |
| 10169 | switch (zir_tag) { | 10195 | switch (zir_tag) { |
| 10170 | .add => { | 10196 | .add => { |