| author | |
| committer | |
| log | 2ffef605c75b62ba49e21bfb3256537a4a2c0a5e |
| tree | ba18403418bcd0c1e6f6f52f9effa51dfd91c878 |
| parent | 4c3c605e5f53c91430efac821ce1b863cbb5bf06 |
This is a bit nasty, mainly because Type.onePossibleValue is now
errorable, which is a quite viral change.16 files changed, 286 insertions(+), 223 deletions(-)
src/Air.zig+1-1| ... | @@ -1485,7 +1485,7 @@ pub fn refToIndexAllowNone(inst: Inst.Ref) ?Inst.Index { | ... | @@ -1485,7 +1485,7 @@ pub fn refToIndexAllowNone(inst: Inst.Ref) ?Inst.Index { |
| 1485 | } | 1485 | } |
| 1486 | 1486 | ||
| 1487 | /// Returns `null` if runtime-known. | 1487 | /// Returns `null` if runtime-known. |
| 1488 | pub fn value(air: Air, inst: Inst.Ref, mod: *const Module) ?Value { | 1488 | pub fn value(air: Air, inst: Inst.Ref, mod: *Module) !?Value { |
| 1489 | const ref_int = @enumToInt(inst); | 1489 | const ref_int = @enumToInt(inst); |
| 1490 | if (ref_int < ref_start_index) { | 1490 | if (ref_int < ref_start_index) { |
| 1491 | const ip_index = @intToEnum(InternPool.Index, ref_int); | 1491 | const ip_index = @intToEnum(InternPool.Index, ref_int); |
src/Module.zig+11-1| ... | @@ -5750,7 +5750,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air { | ... | @@ -5750,7 +5750,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air { |
| 5750 | 5750 | ||
| 5751 | const arg_val = if (!arg_tv.val.isGenericPoison()) | 5751 | const arg_val = if (!arg_tv.val.isGenericPoison()) |
| 5752 | arg_tv.val | 5752 | arg_tv.val |
| 5753 | else if (arg_tv.ty.onePossibleValue(mod)) |opv| | 5753 | else if (try arg_tv.ty.onePossibleValue(mod)) |opv| |
| 5754 | opv | 5754 | opv |
| 5755 | else | 5755 | else |
| 5756 | break :t arg_tv.ty; | 5756 | break :t arg_tv.ty; |
| ... | @@ -6887,6 +6887,16 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { | ... | @@ -6887,6 +6887,16 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { |
| 6887 | } | 6887 | } |
| 6888 | 6888 | ||
| 6889 | pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value { | 6889 | pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value { |
| 6890 | if (std.debug.runtime_safety) { | ||
| 6891 | // TODO: decide if this also works for ABI int types like enums | ||
| 6892 | const tag = ty.zigTypeTag(mod); | ||
| 6893 | assert(tag == .Int or tag == .ComptimeInt); | ||
| 6894 | } | ||
| 6895 | if (@TypeOf(x) == comptime_int) { | ||
| 6896 | if (comptime std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted); | ||
| 6897 | if (comptime std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted); | ||
| 6898 | @compileError("Out-of-range comptime_int passed to Module.intValue"); | ||
| 6899 | } | ||
| 6890 | if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted); | 6900 | if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted); |
| 6891 | if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted); | 6901 | if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted); |
| 6892 | var limbs_buffer: [4]usize = undefined; | 6902 | var limbs_buffer: [4]usize = undefined; |
src/Sema.zig+153-104| ... | @@ -3062,9 +3062,9 @@ fn zirEnumDecl( | ... | @@ -3062,9 +3062,9 @@ fn zirEnumDecl( |
| 3062 | } | 3062 | } |
| 3063 | } else if (any_values) { | 3063 | } else if (any_values) { |
| 3064 | const tag_val = if (last_tag_val) |val| | 3064 | const tag_val = if (last_tag_val) |val| |
| 3065 | try sema.intAdd(val, Value.one, enum_obj.tag_ty) | 3065 | try sema.intAdd(val, try mod.intValue(enum_obj.tag_ty, 1), enum_obj.tag_ty) |
| 3066 | else | 3066 | else |
| 3067 | Value.zero; | 3067 | try mod.intValue(enum_obj.tag_ty, 0); |
| 3068 | last_tag_val = tag_val; | 3068 | last_tag_val = tag_val; |
| 3069 | const copied_tag_val = try tag_val.copy(decl_arena_allocator); | 3069 | const copied_tag_val = try tag_val.copy(decl_arena_allocator); |
| 3070 | const gop_val = enum_obj.values.getOrPutAssumeCapacityContext(copied_tag_val, .{ | 3070 | const gop_val = enum_obj.values.getOrPutAssumeCapacityContext(copied_tag_val, .{ |
| ... | @@ -4709,7 +4709,7 @@ fn zirValidateArrayInit( | ... | @@ -4709,7 +4709,7 @@ fn zirValidateArrayInit( |
| 4709 | // Determine whether the value stored to this pointer is comptime-known. | 4709 | // Determine whether the value stored to this pointer is comptime-known. |
| 4710 | 4710 | ||
| 4711 | if (array_ty.isTuple()) { | 4711 | if (array_ty.isTuple()) { |
| 4712 | if (array_ty.structFieldValueComptime(mod, i)) |opv| { | 4712 | if (try array_ty.structFieldValueComptime(mod, i)) |opv| { |
| 4713 | element_vals[i] = opv; | 4713 | element_vals[i] = opv; |
| 4714 | continue; | 4714 | continue; |
| 4715 | } | 4715 | } |
| ... | @@ -8132,7 +8132,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -8132,7 +8132,7 @@ fn zirErrorToInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 8132 | if (!op_ty.isAnyError()) { | 8132 | if (!op_ty.isAnyError()) { |
| 8133 | const names = op_ty.errorSetNames(); | 8133 | const names = op_ty.errorSetNames(); |
| 8134 | switch (names.len) { | 8134 | switch (names.len) { |
| 8135 | 0 => return sema.addConstant(Type.err_int, Value.zero), | 8135 | 0 => return sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)), |
| 8136 | 1 => return sema.addIntUnsigned(Type.err_int, sema.mod.global_error_set.get(names[0]).?), | 8136 | 1 => return sema.addIntUnsigned(Type.err_int, sema.mod.global_error_set.get(names[0]).?), |
| 8137 | else => {}, | 8137 | else => {}, |
| 8138 | } | 8138 | } |
| ... | @@ -8167,7 +8167,7 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -8167,7 +8167,7 @@ fn zirIntToError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 8167 | try sema.requireRuntimeBlock(block, src, operand_src); | 8167 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 8168 | if (block.wantSafety()) { | 8168 | if (block.wantSafety()) { |
| 8169 | const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand); | 8169 | const is_lt_len = try block.addUnOp(.cmp_lt_errors_len, operand); |
| 8170 | const zero_val = try sema.addConstant(Type.err_int, Value.zero); | 8170 | const zero_val = try sema.addConstant(Type.err_int, try mod.intValue(Type.err_int, 0)); |
| 8171 | const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val); | 8171 | const is_non_zero = try block.addBinOp(.cmp_neq, operand, zero_val); |
| 8172 | const ok = try block.addBinOp(.bit_and, is_lt_len, is_non_zero); | 8172 | const ok = try block.addBinOp(.bit_and, is_lt_len, is_non_zero); |
| 8173 | try sema.addSafetyCheck(block, ok, .invalid_error_code); | 8173 | try sema.addSafetyCheck(block, ok, .invalid_error_code); |
| ... | @@ -9656,7 +9656,7 @@ fn intCast( | ... | @@ -9656,7 +9656,7 @@ fn intCast( |
| 9656 | 9656 | ||
| 9657 | if (wanted_bits == 0) { | 9657 | if (wanted_bits == 0) { |
| 9658 | const ok = if (is_vector) ok: { | 9658 | const ok = if (is_vector) ok: { |
| 9659 | const zeros = try Value.Tag.repeated.create(sema.arena, Value.zero); | 9659 | const zeros = try Value.Tag.repeated.create(sema.arena, try mod.intValue(operand_scalar_ty, 0)); |
| 9660 | const zero_inst = try sema.addConstant(sema.typeOf(operand), zeros); | 9660 | const zero_inst = try sema.addConstant(sema.typeOf(operand), zeros); |
| 9661 | const is_in_range = try block.addCmpVector(operand, zero_inst, .eq); | 9661 | const is_in_range = try block.addCmpVector(operand, zero_inst, .eq); |
| 9662 | const all_in_range = try block.addInst(.{ | 9662 | const all_in_range = try block.addInst(.{ |
| ... | @@ -9665,7 +9665,7 @@ fn intCast( | ... | @@ -9665,7 +9665,7 @@ fn intCast( |
| 9665 | }); | 9665 | }); |
| 9666 | break :ok all_in_range; | 9666 | break :ok all_in_range; |
| 9667 | } else ok: { | 9667 | } else ok: { |
| 9668 | const zero_inst = try sema.addConstant(sema.typeOf(operand), Value.zero); | 9668 | const zero_inst = try sema.addConstant(sema.typeOf(operand), try mod.intValue(operand_ty, 0)); |
| 9669 | const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst); | 9669 | const is_in_range = try block.addBinOp(.cmp_lte, operand, zero_inst); |
| 9670 | break :ok is_in_range; | 9670 | break :ok is_in_range; |
| 9671 | }; | 9671 | }; |
| ... | @@ -9705,8 +9705,9 @@ fn intCast( | ... | @@ -9705,8 +9705,9 @@ fn intCast( |
| 9705 | // If the destination type is signed, then we need to double its | 9705 | // If the destination type is signed, then we need to double its |
| 9706 | // range to account for negative values. | 9706 | // range to account for negative values. |
| 9707 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { | 9707 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { |
| 9708 | const range_minus_one = try dest_max_val.shl(Value.one, unsigned_operand_ty, sema.arena, sema.mod); | 9708 | const one = try mod.intValue(unsigned_operand_ty, 1); |
| 9709 | break :range_val try sema.intAdd(range_minus_one, Value.one, unsigned_operand_ty); | 9709 | const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, sema.mod); |
| 9710 | break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty); | ||
| 9710 | } else dest_max_val; | 9711 | } else dest_max_val; |
| 9711 | const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val); | 9712 | const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val); |
| 9712 | 9713 | ||
| ... | @@ -9747,7 +9748,7 @@ fn intCast( | ... | @@ -9747,7 +9748,7 @@ fn intCast( |
| 9747 | // no shrinkage, yes sign loss | 9748 | // no shrinkage, yes sign loss |
| 9748 | // requirement: signed to unsigned >= 0 | 9749 | // requirement: signed to unsigned >= 0 |
| 9749 | const ok = if (is_vector) ok: { | 9750 | const ok = if (is_vector) ok: { |
| 9750 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); | 9751 | const zero_val = try Value.Tag.repeated.create(sema.arena, try mod.intValue(operand_scalar_ty, 0)); |
| 9751 | const zero_inst = try sema.addConstant(operand_ty, zero_val); | 9752 | const zero_inst = try sema.addConstant(operand_ty, zero_val); |
| 9752 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte); | 9753 | const is_in_range = try block.addCmpVector(operand, zero_inst, .gte); |
| 9753 | const all_in_range = try block.addInst(.{ | 9754 | const all_in_range = try block.addInst(.{ |
| ... | @@ -9759,7 +9760,7 @@ fn intCast( | ... | @@ -9759,7 +9760,7 @@ fn intCast( |
| 9759 | }); | 9760 | }); |
| 9760 | break :ok all_in_range; | 9761 | break :ok all_in_range; |
| 9761 | } else ok: { | 9762 | } else ok: { |
| 9762 | const zero_inst = try sema.addConstant(operand_ty, Value.zero); | 9763 | const zero_inst = try sema.addConstant(operand_ty, try mod.intValue(operand_ty, 0)); |
| 9763 | const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst); | 9764 | const is_in_range = try block.addBinOp(.cmp_gte, operand, zero_inst); |
| 9764 | break :ok is_in_range; | 9765 | break :ok is_in_range; |
| 9765 | }; | 9766 | }; |
| ... | @@ -11250,7 +11251,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11250,7 +11251,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11250 | 11251 | ||
| 11251 | while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({ | 11252 | while (item.compareScalar(.lte, item_last, operand_ty, mod)) : ({ |
| 11252 | // Previous validation has resolved any possible lazy values. | 11253 | // Previous validation has resolved any possible lazy values. |
| 11253 | item = try sema.intAddScalar(item, Value.one, operand_ty); | 11254 | item = try sema.intAddScalar(item, try mod.intValue(operand_ty, 1), operand_ty); |
| 11254 | }) { | 11255 | }) { |
| 11255 | cases_len += 1; | 11256 | cases_len += 1; |
| 11256 | 11257 | ||
| ... | @@ -11696,7 +11697,7 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -11696,7 +11697,7 @@ const RangeSetUnhandledIterator = struct { |
| 11696 | fn next(it: *RangeSetUnhandledIterator) !?Value { | 11697 | fn next(it: *RangeSetUnhandledIterator) !?Value { |
| 11697 | while (it.range_i < it.ranges.len) : (it.range_i += 1) { | 11698 | while (it.range_i < it.ranges.len) : (it.range_i += 1) { |
| 11698 | if (!it.first) { | 11699 | if (!it.first) { |
| 11699 | it.cur = try it.sema.intAddScalar(it.cur, Value.one, it.ty); | 11700 | it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty); |
| 11700 | } | 11701 | } |
| 11701 | it.first = false; | 11702 | it.first = false; |
| 11702 | if (it.cur.compareScalar(.lt, it.ranges[it.range_i].first, it.ty, it.sema.mod)) { | 11703 | if (it.cur.compareScalar(.lt, it.ranges[it.range_i].first, it.ty, it.sema.mod)) { |
| ... | @@ -11705,7 +11706,7 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -11705,7 +11706,7 @@ const RangeSetUnhandledIterator = struct { |
| 11705 | it.cur = it.ranges[it.range_i].last; | 11706 | it.cur = it.ranges[it.range_i].last; |
| 11706 | } | 11707 | } |
| 11707 | if (!it.first) { | 11708 | if (!it.first) { |
| 11708 | it.cur = try it.sema.intAddScalar(it.cur, Value.one, it.ty); | 11709 | it.cur = try it.sema.intAddScalar(it.cur, try it.sema.mod.intValue(it.ty, 1), it.ty); |
| 11709 | } | 11710 | } |
| 11710 | it.first = false; | 11711 | it.first = false; |
| 11711 | if (it.cur.compareScalar(.lte, it.max, it.ty, it.sema.mod)) { | 11712 | if (it.cur.compareScalar(.lte, it.max, it.ty, it.sema.mod)) { |
| ... | @@ -12150,7 +12151,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -12150,7 +12151,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 12150 | // into the final binary, and never loads the data into memory. | 12151 | // into the final binary, and never loads the data into memory. |
| 12151 | // - When a Decl is destroyed, it can free the `*Module.EmbedFile`. | 12152 | // - When a Decl is destroyed, it can free the `*Module.EmbedFile`. |
| 12152 | embed_file.owner_decl = try anon_decl.finish( | 12153 | embed_file.owner_decl = try anon_decl.finish( |
| 12153 | try Type.array(anon_decl.arena(), embed_file.bytes.len, Value.zero, Type.u8, mod), | 12154 | try Type.array(anon_decl.arena(), embed_file.bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 12154 | try Value.Tag.bytes.create(anon_decl.arena(), bytes_including_null), | 12155 | try Value.Tag.bytes.create(anon_decl.arena(), bytes_including_null), |
| 12155 | 0, // default alignment | 12156 | 0, // default alignment |
| 12156 | ); | 12157 | ); |
| ... | @@ -12235,14 +12236,14 @@ fn zirShl( | ... | @@ -12235,14 +12236,14 @@ fn zirShl( |
| 12235 | var i: usize = 0; | 12236 | var i: usize = 0; |
| 12236 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | 12237 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { |
| 12237 | const rhs_elem = try rhs_val.elemValue(sema.mod, i); | 12238 | const rhs_elem = try rhs_val.elemValue(sema.mod, i); |
| 12238 | if (rhs_elem.compareHetero(.lt, Value.zero, mod)) { | 12239 | if (rhs_elem.compareHetero(.lt, try mod.intValue(scalar_rhs_ty, 0), mod)) { |
| 12239 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ | 12240 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| 12240 | rhs_elem.fmtValue(scalar_ty, sema.mod), | 12241 | rhs_elem.fmtValue(scalar_ty, sema.mod), |
| 12241 | i, | 12242 | i, |
| 12242 | }); | 12243 | }); |
| 12243 | } | 12244 | } |
| 12244 | } | 12245 | } |
| 12245 | } else if (rhs_val.compareHetero(.lt, Value.zero, mod)) { | 12246 | } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { |
| 12246 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ | 12247 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| 12247 | rhs_val.fmtValue(scalar_ty, sema.mod), | 12248 | rhs_val.fmtValue(scalar_ty, sema.mod), |
| 12248 | }); | 12249 | }); |
| ... | @@ -12348,7 +12349,7 @@ fn zirShl( | ... | @@ -12348,7 +12349,7 @@ fn zirShl( |
| 12348 | }) | 12349 | }) |
| 12349 | else | 12350 | else |
| 12350 | ov_bit; | 12351 | ov_bit; |
| 12351 | const zero_ov = try sema.addConstant(Type.u1, Value.zero); | 12352 | const zero_ov = try sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0)); |
| 12352 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); | 12353 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); |
| 12353 | 12354 | ||
| 12354 | try sema.addSafetyCheck(block, no_ov, .shl_overflow); | 12355 | try sema.addSafetyCheck(block, no_ov, .shl_overflow); |
| ... | @@ -12417,14 +12418,14 @@ fn zirShr( | ... | @@ -12417,14 +12418,14 @@ fn zirShr( |
| 12417 | var i: usize = 0; | 12418 | var i: usize = 0; |
| 12418 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { | 12419 | while (i < rhs_ty.vectorLen(mod)) : (i += 1) { |
| 12419 | const rhs_elem = try rhs_val.elemValue(sema.mod, i); | 12420 | const rhs_elem = try rhs_val.elemValue(sema.mod, i); |
| 12420 | if (rhs_elem.compareHetero(.lt, Value.zero, mod)) { | 12421 | if (rhs_elem.compareHetero(.lt, try mod.intValue(rhs_ty.childType(mod), 0), mod)) { |
| 12421 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ | 12422 | return sema.fail(block, rhs_src, "shift by negative amount '{}' at index '{d}'", .{ |
| 12422 | rhs_elem.fmtValue(scalar_ty, sema.mod), | 12423 | rhs_elem.fmtValue(scalar_ty, sema.mod), |
| 12423 | i, | 12424 | i, |
| 12424 | }); | 12425 | }); |
| 12425 | } | 12426 | } |
| 12426 | } | 12427 | } |
| 12427 | } else if (rhs_val.compareHetero(.lt, Value.zero, mod)) { | 12428 | } else if (rhs_val.compareHetero(.lt, try mod.intValue(rhs_ty, 0), mod)) { |
| 12428 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ | 12429 | return sema.fail(block, rhs_src, "shift by negative amount '{}'", .{ |
| 12429 | rhs_val.fmtValue(scalar_ty, sema.mod), | 12430 | rhs_val.fmtValue(scalar_ty, sema.mod), |
| 12430 | }); | 12431 | }); |
| ... | @@ -13156,9 +13157,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -13156,9 +13157,9 @@ fn zirNegate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 13156 | } | 13157 | } |
| 13157 | 13158 | ||
| 13158 | const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector) | 13159 | const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector) |
| 13159 | try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero)) | 13160 | try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, try mod.intValue(rhs_scalar_ty, 0))) |
| 13160 | else | 13161 | else |
| 13161 | try sema.resolveInst(.zero); | 13162 | try sema.addConstant(rhs_ty, try mod.intValue(rhs_ty, 0)); |
| 13162 | 13163 | ||
| 13163 | return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true); | 13164 | return sema.analyzeArithmetic(block, .sub, lhs, rhs, src, lhs_src, rhs_src, true); |
| 13164 | } | 13165 | } |
| ... | @@ -13180,9 +13181,9 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -13180,9 +13181,9 @@ fn zirNegateWrap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 13180 | } | 13181 | } |
| 13181 | 13182 | ||
| 13182 | const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector) | 13183 | const lhs = if (rhs_ty.zigTypeTag(mod) == .Vector) |
| 13183 | try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, Value.zero)) | 13184 | try sema.addConstant(rhs_ty, try Value.Tag.repeated.create(sema.arena, try mod.intValue(rhs_scalar_ty, 0))) |
| 13184 | else | 13185 | else |
| 13185 | try sema.resolveInst(.zero); | 13186 | try sema.addConstant(rhs_ty, try mod.intValue(rhs_ty, 0)); |
| 13186 | 13187 | ||
| 13187 | return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true); | 13188 | return sema.analyzeArithmetic(block, .subwrap, lhs, rhs, src, lhs_src, rhs_src, true); |
| 13188 | } | 13189 | } |
| ... | @@ -13293,9 +13294,14 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -13293,9 +13294,14 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 13293 | if (maybe_lhs_val) |lhs_val| { | 13294 | if (maybe_lhs_val) |lhs_val| { |
| 13294 | if (!lhs_val.isUndef()) { | 13295 | if (!lhs_val.isUndef()) { |
| 13295 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13296 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13297 | const scalar_zero = switch (scalar_tag) { | ||
| 13298 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 13299 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 13300 | else => unreachable, | ||
| 13301 | }; | ||
| 13296 | const zero_val = if (is_vector) b: { | 13302 | const zero_val = if (is_vector) b: { |
| 13297 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 13303 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 13298 | } else Value.zero; | 13304 | } else scalar_zero; |
| 13299 | return sema.addConstant(resolved_type, zero_val); | 13305 | return sema.addConstant(resolved_type, zero_val); |
| 13300 | } | 13306 | } |
| 13301 | } | 13307 | } |
| ... | @@ -13318,7 +13324,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -13318,7 +13324,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 13318 | if (lhs_val.isUndef()) { | 13324 | if (lhs_val.isUndef()) { |
| 13319 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | 13325 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { |
| 13320 | if (maybe_rhs_val) |rhs_val| { | 13326 | if (maybe_rhs_val) |rhs_val| { |
| 13321 | if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) { | 13327 | if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) { |
| 13322 | return sema.addConstUndef(resolved_type); | 13328 | return sema.addConstUndef(resolved_type); |
| 13323 | } | 13329 | } |
| 13324 | } | 13330 | } |
| ... | @@ -13427,9 +13433,14 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13427,9 +13433,14 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13427 | return sema.failWithUseOfUndef(block, rhs_src); | 13433 | return sema.failWithUseOfUndef(block, rhs_src); |
| 13428 | } else { | 13434 | } else { |
| 13429 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13435 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13436 | const scalar_zero = switch (scalar_tag) { | ||
| 13437 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 13438 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 13439 | else => unreachable, | ||
| 13440 | }; | ||
| 13430 | const zero_val = if (is_vector) b: { | 13441 | const zero_val = if (is_vector) b: { |
| 13431 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 13442 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 13432 | } else Value.zero; | 13443 | } else scalar_zero; |
| 13433 | return sema.addConstant(resolved_type, zero_val); | 13444 | return sema.addConstant(resolved_type, zero_val); |
| 13434 | } | 13445 | } |
| 13435 | } | 13446 | } |
| ... | @@ -13507,8 +13518,13 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13507,8 +13518,13 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13507 | } else ok: { | 13518 | } else ok: { |
| 13508 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); | 13519 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); |
| 13509 | 13520 | ||
| 13521 | const scalar_zero = switch (scalar_tag) { | ||
| 13522 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 13523 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 13524 | else => unreachable, | ||
| 13525 | }; | ||
| 13510 | if (resolved_type.zigTypeTag(mod) == .Vector) { | 13526 | if (resolved_type.zigTypeTag(mod) == .Vector) { |
| 13511 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); | 13527 | const zero_val = try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 13512 | const zero = try sema.addConstant(resolved_type, zero_val); | 13528 | const zero = try sema.addConstant(resolved_type, zero_val); |
| 13513 | const eql = try block.addCmpVector(remainder, zero, .eq); | 13529 | const eql = try block.addCmpVector(remainder, zero, .eq); |
| 13514 | break :ok try block.addInst(.{ | 13530 | break :ok try block.addInst(.{ |
| ... | @@ -13519,7 +13535,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13519,7 +13535,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13519 | } }, | 13535 | } }, |
| 13520 | }); | 13536 | }); |
| 13521 | } else { | 13537 | } else { |
| 13522 | const zero = try sema.addConstant(resolved_type, Value.zero); | 13538 | const zero = try sema.addConstant(resolved_type, scalar_zero); |
| 13523 | const is_in_range = try block.addBinOp(.cmp_eq, remainder, zero); | 13539 | const is_in_range = try block.addBinOp(.cmp_eq, remainder, zero); |
| 13524 | break :ok is_in_range; | 13540 | break :ok is_in_range; |
| 13525 | } | 13541 | } |
| ... | @@ -13592,9 +13608,14 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13592,9 +13608,14 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13592 | if (maybe_lhs_val) |lhs_val| { | 13608 | if (maybe_lhs_val) |lhs_val| { |
| 13593 | if (!lhs_val.isUndef()) { | 13609 | if (!lhs_val.isUndef()) { |
| 13594 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13610 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13611 | const scalar_zero = switch (scalar_tag) { | ||
| 13612 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 13613 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 13614 | else => unreachable, | ||
| 13615 | }; | ||
| 13595 | const zero_val = if (is_vector) b: { | 13616 | const zero_val = if (is_vector) b: { |
| 13596 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 13617 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 13597 | } else Value.zero; | 13618 | } else scalar_zero; |
| 13598 | return sema.addConstant(resolved_type, zero_val); | 13619 | return sema.addConstant(resolved_type, zero_val); |
| 13599 | } | 13620 | } |
| 13600 | } | 13621 | } |
| ... | @@ -13612,7 +13633,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13612,7 +13633,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13612 | if (lhs_val.isUndef()) { | 13633 | if (lhs_val.isUndef()) { |
| 13613 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | 13634 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { |
| 13614 | if (maybe_rhs_val) |rhs_val| { | 13635 | if (maybe_rhs_val) |rhs_val| { |
| 13615 | if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) { | 13636 | if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) { |
| 13616 | return sema.addConstUndef(resolved_type); | 13637 | return sema.addConstUndef(resolved_type); |
| 13617 | } | 13638 | } |
| 13618 | } | 13639 | } |
| ... | @@ -13708,9 +13729,14 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13708,9 +13729,14 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13708 | if (maybe_lhs_val) |lhs_val| { | 13729 | if (maybe_lhs_val) |lhs_val| { |
| 13709 | if (!lhs_val.isUndef()) { | 13730 | if (!lhs_val.isUndef()) { |
| 13710 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13731 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13732 | const scalar_zero = switch (scalar_tag) { | ||
| 13733 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 13734 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 13735 | else => unreachable, | ||
| 13736 | }; | ||
| 13711 | const zero_val = if (is_vector) b: { | 13737 | const zero_val = if (is_vector) b: { |
| 13712 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 13738 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 13713 | } else Value.zero; | 13739 | } else scalar_zero; |
| 13714 | return sema.addConstant(resolved_type, zero_val); | 13740 | return sema.addConstant(resolved_type, zero_val); |
| 13715 | } | 13741 | } |
| 13716 | } | 13742 | } |
| ... | @@ -13727,7 +13753,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13727,7 +13753,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13727 | if (lhs_val.isUndef()) { | 13753 | if (lhs_val.isUndef()) { |
| 13728 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { | 13754 | if (lhs_scalar_ty.isSignedInt(mod) and rhs_scalar_ty.isSignedInt(mod)) { |
| 13729 | if (maybe_rhs_val) |rhs_val| { | 13755 | if (maybe_rhs_val) |rhs_val| { |
| 13730 | if (try sema.compareAll(rhs_val, .neq, Value.negative_one, resolved_type)) { | 13756 | if (try sema.compareAll(rhs_val, .neq, try mod.intValue(resolved_type, -1), resolved_type)) { |
| 13731 | return sema.addConstUndef(resolved_type); | 13757 | return sema.addConstUndef(resolved_type); |
| 13732 | } | 13758 | } |
| 13733 | } | 13759 | } |
| ... | @@ -13862,8 +13888,9 @@ fn addDivByZeroSafety( | ... | @@ -13862,8 +13888,9 @@ fn addDivByZeroSafety( |
| 13862 | if (maybe_rhs_val != null) return; | 13888 | if (maybe_rhs_val != null) return; |
| 13863 | 13889 | ||
| 13864 | const mod = sema.mod; | 13890 | const mod = sema.mod; |
| 13891 | const scalar_zero = if (is_int) try mod.intValue(resolved_type.scalarType(mod), 0) else Value.float_zero; // TODO migrate to internpool | ||
| 13865 | const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: { | 13892 | const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: { |
| 13866 | const zero_val = try Value.Tag.repeated.create(sema.arena, Value.zero); | 13893 | const zero_val = try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 13867 | const zero = try sema.addConstant(resolved_type, zero_val); | 13894 | const zero = try sema.addConstant(resolved_type, zero_val); |
| 13868 | const ok = try block.addCmpVector(casted_rhs, zero, .neq); | 13895 | const ok = try block.addCmpVector(casted_rhs, zero, .neq); |
| 13869 | break :ok try block.addInst(.{ | 13896 | break :ok try block.addInst(.{ |
| ... | @@ -13874,7 +13901,7 @@ fn addDivByZeroSafety( | ... | @@ -13874,7 +13901,7 @@ fn addDivByZeroSafety( |
| 13874 | } }, | 13901 | } }, |
| 13875 | }); | 13902 | }); |
| 13876 | } else ok: { | 13903 | } else ok: { |
| 13877 | const zero = try sema.addConstant(resolved_type, Value.zero); | 13904 | const zero = try sema.addConstant(resolved_type, scalar_zero); |
| 13878 | break :ok try block.addBinOp(if (is_int) .cmp_neq else .cmp_neq_optimized, casted_rhs, zero); | 13905 | break :ok try block.addBinOp(if (is_int) .cmp_neq else .cmp_neq_optimized, casted_rhs, zero); |
| 13879 | }; | 13906 | }; |
| 13880 | try sema.addSafetyCheck(block, ok, .divide_by_zero); | 13907 | try sema.addSafetyCheck(block, ok, .divide_by_zero); |
| ... | @@ -13946,9 +13973,14 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -13946,9 +13973,14 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 13946 | return sema.failWithUseOfUndef(block, lhs_src); | 13973 | return sema.failWithUseOfUndef(block, lhs_src); |
| 13947 | } | 13974 | } |
| 13948 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13975 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13976 | const scalar_zero = switch (scalar_tag) { | ||
| 13977 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 13978 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 13979 | else => unreachable, | ||
| 13980 | }; | ||
| 13949 | const zero_val = if (is_vector) b: { | 13981 | const zero_val = if (is_vector) b: { |
| 13950 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 13982 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 13951 | } else Value.zero; | 13983 | } else scalar_zero; |
| 13952 | return sema.addConstant(resolved_type, zero_val); | 13984 | return sema.addConstant(resolved_type, zero_val); |
| 13953 | } | 13985 | } |
| 13954 | } else if (lhs_scalar_ty.isSignedInt(mod)) { | 13986 | } else if (lhs_scalar_ty.isSignedInt(mod)) { |
| ... | @@ -14325,6 +14357,7 @@ fn zirOverflowArithmetic( | ... | @@ -14325,6 +14357,7 @@ fn zirOverflowArithmetic( |
| 14325 | wrapped: Value = Value.@"unreachable", | 14357 | wrapped: Value = Value.@"unreachable", |
| 14326 | overflow_bit: Value, | 14358 | overflow_bit: Value, |
| 14327 | } = result: { | 14359 | } = result: { |
| 14360 | const zero = try mod.intValue(dest_ty.scalarType(mod), 0); | ||
| 14328 | switch (zir_tag) { | 14361 | switch (zir_tag) { |
| 14329 | .add_with_overflow => { | 14362 | .add_with_overflow => { |
| 14330 | // If either of the arguments is zero, `false` is returned and the other is stored | 14363 | // If either of the arguments is zero, `false` is returned and the other is stored |
| ... | @@ -14332,12 +14365,12 @@ fn zirOverflowArithmetic( | ... | @@ -14332,12 +14365,12 @@ fn zirOverflowArithmetic( |
| 14332 | // Otherwise, if either of the argument is undefined, undefined is returned. | 14365 | // Otherwise, if either of the argument is undefined, undefined is returned. |
| 14333 | if (maybe_lhs_val) |lhs_val| { | 14366 | if (maybe_lhs_val) |lhs_val| { |
| 14334 | if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) { | 14367 | if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) { |
| 14335 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs }; | 14368 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs }; |
| 14336 | } | 14369 | } |
| 14337 | } | 14370 | } |
| 14338 | if (maybe_rhs_val) |rhs_val| { | 14371 | if (maybe_rhs_val) |rhs_val| { |
| 14339 | if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) { | 14372 | if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) { |
| 14340 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; | 14373 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs }; |
| 14341 | } | 14374 | } |
| 14342 | } | 14375 | } |
| 14343 | if (maybe_lhs_val) |lhs_val| { | 14376 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14358,7 +14391,7 @@ fn zirOverflowArithmetic( | ... | @@ -14358,7 +14391,7 @@ fn zirOverflowArithmetic( |
| 14358 | if (rhs_val.isUndef()) { | 14391 | if (rhs_val.isUndef()) { |
| 14359 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; | 14392 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| 14360 | } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 14393 | } else if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 14361 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; | 14394 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs }; |
| 14362 | } else if (maybe_lhs_val) |lhs_val| { | 14395 | } else if (maybe_lhs_val) |lhs_val| { |
| 14363 | if (lhs_val.isUndef()) { | 14396 | if (lhs_val.isUndef()) { |
| 14364 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; | 14397 | break :result .{ .overflow_bit = Value.undef, .wrapped = Value.undef }; |
| ... | @@ -14373,12 +14406,13 @@ fn zirOverflowArithmetic( | ... | @@ -14373,12 +14406,13 @@ fn zirOverflowArithmetic( |
| 14373 | // If either of the arguments is zero, the result is zero and no overflow occured. | 14406 | // If either of the arguments is zero, the result is zero and no overflow occured. |
| 14374 | // If either of the arguments is one, the result is the other and no overflow occured. | 14407 | // If either of the arguments is one, the result is the other and no overflow occured. |
| 14375 | // Otherwise, if either of the arguments is undefined, both results are undefined. | 14408 | // Otherwise, if either of the arguments is undefined, both results are undefined. |
| 14409 | const scalar_one = try mod.intValue(dest_ty.scalarType(mod), 1); | ||
| 14376 | if (maybe_lhs_val) |lhs_val| { | 14410 | if (maybe_lhs_val) |lhs_val| { |
| 14377 | if (!lhs_val.isUndef()) { | 14411 | if (!lhs_val.isUndef()) { |
| 14378 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 14412 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 14379 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; | 14413 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs }; |
| 14380 | } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, Value.one), dest_ty)) { | 14414 | } else if (try sema.compareAll(lhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) { |
| 14381 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs }; | 14415 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs }; |
| 14382 | } | 14416 | } |
| 14383 | } | 14417 | } |
| 14384 | } | 14418 | } |
| ... | @@ -14386,9 +14420,9 @@ fn zirOverflowArithmetic( | ... | @@ -14386,9 +14420,9 @@ fn zirOverflowArithmetic( |
| 14386 | if (maybe_rhs_val) |rhs_val| { | 14420 | if (maybe_rhs_val) |rhs_val| { |
| 14387 | if (!rhs_val.isUndef()) { | 14421 | if (!rhs_val.isUndef()) { |
| 14388 | if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 14422 | if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 14389 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = rhs }; | 14423 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = rhs }; |
| 14390 | } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, Value.one), dest_ty)) { | 14424 | } else if (try sema.compareAll(rhs_val, .eq, try maybeRepeated(sema, dest_ty, scalar_one), dest_ty)) { |
| 14391 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; | 14425 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs }; |
| 14392 | } | 14426 | } |
| 14393 | } | 14427 | } |
| 14394 | } | 14428 | } |
| ... | @@ -14410,12 +14444,12 @@ fn zirOverflowArithmetic( | ... | @@ -14410,12 +14444,12 @@ fn zirOverflowArithmetic( |
| 14410 | // Oterhwise if either of the arguments is undefined, both results are undefined. | 14444 | // Oterhwise if either of the arguments is undefined, both results are undefined. |
| 14411 | if (maybe_lhs_val) |lhs_val| { | 14445 | if (maybe_lhs_val) |lhs_val| { |
| 14412 | if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) { | 14446 | if (!lhs_val.isUndef() and (try lhs_val.compareAllWithZeroAdvanced(.eq, sema))) { |
| 14413 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; | 14447 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs }; |
| 14414 | } | 14448 | } |
| 14415 | } | 14449 | } |
| 14416 | if (maybe_rhs_val) |rhs_val| { | 14450 | if (maybe_rhs_val) |rhs_val| { |
| 14417 | if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) { | 14451 | if (!rhs_val.isUndef() and (try rhs_val.compareAllWithZeroAdvanced(.eq, sema))) { |
| 14418 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, Value.zero), .inst = lhs }; | 14452 | break :result .{ .overflow_bit = try maybeRepeated(sema, dest_ty, zero), .inst = lhs }; |
| 14419 | } | 14453 | } |
| 14420 | } | 14454 | } |
| 14421 | if (maybe_lhs_val) |lhs_val| { | 14455 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14766,6 +14800,11 @@ fn analyzeArithmetic( | ... | @@ -14766,6 +14800,11 @@ fn analyzeArithmetic( |
| 14766 | // If either of the operands are inf, and the other operand is zero, | 14800 | // If either of the operands are inf, and the other operand is zero, |
| 14767 | // the result is nan. | 14801 | // the result is nan. |
| 14768 | // If either of the operands are nan, the result is nan. | 14802 | // If either of the operands are nan, the result is nan. |
| 14803 | const scalar_zero = switch (scalar_tag) { | ||
| 14804 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 14805 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 14806 | else => unreachable, | ||
| 14807 | }; | ||
| 14769 | if (maybe_lhs_val) |lhs_val| { | 14808 | if (maybe_lhs_val) |lhs_val| { |
| 14770 | if (!lhs_val.isUndef()) { | 14809 | if (!lhs_val.isUndef()) { |
| 14771 | if (lhs_val.isNan()) { | 14810 | if (lhs_val.isNan()) { |
| ... | @@ -14783,11 +14822,11 @@ fn analyzeArithmetic( | ... | @@ -14783,11 +14822,11 @@ fn analyzeArithmetic( |
| 14783 | break :lz; | 14822 | break :lz; |
| 14784 | } | 14823 | } |
| 14785 | const zero_val = if (is_vector) b: { | 14824 | const zero_val = if (is_vector) b: { |
| 14786 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 14825 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 14787 | } else Value.zero; | 14826 | } else scalar_zero; |
| 14788 | return sema.addConstant(resolved_type, zero_val); | 14827 | return sema.addConstant(resolved_type, zero_val); |
| 14789 | } | 14828 | } |
| 14790 | if (try sema.compareAll(lhs_val, .eq, Value.one, resolved_type)) { | 14829 | if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { |
| 14791 | return casted_rhs; | 14830 | return casted_rhs; |
| 14792 | } | 14831 | } |
| 14793 | } | 14832 | } |
| ... | @@ -14813,11 +14852,11 @@ fn analyzeArithmetic( | ... | @@ -14813,11 +14852,11 @@ fn analyzeArithmetic( |
| 14813 | break :rz; | 14852 | break :rz; |
| 14814 | } | 14853 | } |
| 14815 | const zero_val = if (is_vector) b: { | 14854 | const zero_val = if (is_vector) b: { |
| 14816 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 14855 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 14817 | } else Value.zero; | 14856 | } else scalar_zero; |
| 14818 | return sema.addConstant(resolved_type, zero_val); | 14857 | return sema.addConstant(resolved_type, zero_val); |
| 14819 | } | 14858 | } |
| 14820 | if (try sema.compareAll(rhs_val, .eq, Value.one, resolved_type)) { | 14859 | if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { |
| 14821 | return casted_lhs; | 14860 | return casted_lhs; |
| 14822 | } | 14861 | } |
| 14823 | if (maybe_lhs_val) |lhs_val| { | 14862 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14849,15 +14888,20 @@ fn analyzeArithmetic( | ... | @@ -14849,15 +14888,20 @@ fn analyzeArithmetic( |
| 14849 | // If either of the operands are zero, result is zero. | 14888 | // If either of the operands are zero, result is zero. |
| 14850 | // If either of the operands are one, result is the other operand. | 14889 | // If either of the operands are one, result is the other operand. |
| 14851 | // If either of the operands are undefined, result is undefined. | 14890 | // If either of the operands are undefined, result is undefined. |
| 14891 | const scalar_zero = switch (scalar_tag) { | ||
| 14892 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 14893 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 14894 | else => unreachable, | ||
| 14895 | }; | ||
| 14852 | if (maybe_lhs_val) |lhs_val| { | 14896 | if (maybe_lhs_val) |lhs_val| { |
| 14853 | if (!lhs_val.isUndef()) { | 14897 | if (!lhs_val.isUndef()) { |
| 14854 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 14898 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 14855 | const zero_val = if (is_vector) b: { | 14899 | const zero_val = if (is_vector) b: { |
| 14856 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 14900 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 14857 | } else Value.zero; | 14901 | } else scalar_zero; |
| 14858 | return sema.addConstant(resolved_type, zero_val); | 14902 | return sema.addConstant(resolved_type, zero_val); |
| 14859 | } | 14903 | } |
| 14860 | if (try sema.compareAll(lhs_val, .eq, Value.one, resolved_type)) { | 14904 | if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { |
| 14861 | return casted_rhs; | 14905 | return casted_rhs; |
| 14862 | } | 14906 | } |
| 14863 | } | 14907 | } |
| ... | @@ -14869,11 +14913,11 @@ fn analyzeArithmetic( | ... | @@ -14869,11 +14913,11 @@ fn analyzeArithmetic( |
| 14869 | } | 14913 | } |
| 14870 | if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 14914 | if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 14871 | const zero_val = if (is_vector) b: { | 14915 | const zero_val = if (is_vector) b: { |
| 14872 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 14916 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 14873 | } else Value.zero; | 14917 | } else scalar_zero; |
| 14874 | return sema.addConstant(resolved_type, zero_val); | 14918 | return sema.addConstant(resolved_type, zero_val); |
| 14875 | } | 14919 | } |
| 14876 | if (try sema.compareAll(rhs_val, .eq, Value.one, resolved_type)) { | 14920 | if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { |
| 14877 | return casted_lhs; | 14921 | return casted_lhs; |
| 14878 | } | 14922 | } |
| 14879 | if (maybe_lhs_val) |lhs_val| { | 14923 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14892,15 +14936,20 @@ fn analyzeArithmetic( | ... | @@ -14892,15 +14936,20 @@ fn analyzeArithmetic( |
| 14892 | // If either of the operands are zero, result is zero. | 14936 | // If either of the operands are zero, result is zero. |
| 14893 | // If either of the operands are one, result is the other operand. | 14937 | // If either of the operands are one, result is the other operand. |
| 14894 | // If either of the operands are undefined, result is undefined. | 14938 | // If either of the operands are undefined, result is undefined. |
| 14939 | const scalar_zero = switch (scalar_tag) { | ||
| 14940 | .ComptimeFloat, .Float => Value.float_zero, // TODO migrate to internpool | ||
| 14941 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | ||
| 14942 | else => unreachable, | ||
| 14943 | }; | ||
| 14895 | if (maybe_lhs_val) |lhs_val| { | 14944 | if (maybe_lhs_val) |lhs_val| { |
| 14896 | if (!lhs_val.isUndef()) { | 14945 | if (!lhs_val.isUndef()) { |
| 14897 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 14946 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 14898 | const zero_val = if (is_vector) b: { | 14947 | const zero_val = if (is_vector) b: { |
| 14899 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 14948 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 14900 | } else Value.zero; | 14949 | } else scalar_zero; |
| 14901 | return sema.addConstant(resolved_type, zero_val); | 14950 | return sema.addConstant(resolved_type, zero_val); |
| 14902 | } | 14951 | } |
| 14903 | if (try sema.compareAll(lhs_val, .eq, Value.one, resolved_type)) { | 14952 | if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { |
| 14904 | return casted_rhs; | 14953 | return casted_rhs; |
| 14905 | } | 14954 | } |
| 14906 | } | 14955 | } |
| ... | @@ -14911,11 +14960,11 @@ fn analyzeArithmetic( | ... | @@ -14911,11 +14960,11 @@ fn analyzeArithmetic( |
| 14911 | } | 14960 | } |
| 14912 | if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 14961 | if (try rhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 14913 | const zero_val = if (is_vector) b: { | 14962 | const zero_val = if (is_vector) b: { |
| 14914 | break :b try Value.Tag.repeated.create(sema.arena, Value.zero); | 14963 | break :b try Value.Tag.repeated.create(sema.arena, scalar_zero); |
| 14915 | } else Value.zero; | 14964 | } else scalar_zero; |
| 14916 | return sema.addConstant(resolved_type, zero_val); | 14965 | return sema.addConstant(resolved_type, zero_val); |
| 14917 | } | 14966 | } |
| 14918 | if (try sema.compareAll(rhs_val, .eq, Value.one, resolved_type)) { | 14967 | if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { |
| 14919 | return casted_lhs; | 14968 | return casted_lhs; |
| 14920 | } | 14969 | } |
| 14921 | if (maybe_lhs_val) |lhs_val| { | 14970 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14968,7 +15017,7 @@ fn analyzeArithmetic( | ... | @@ -14968,7 +15017,7 @@ fn analyzeArithmetic( |
| 14968 | }) | 15017 | }) |
| 14969 | else | 15018 | else |
| 14970 | ov_bit; | 15019 | ov_bit; |
| 14971 | const zero_ov = try sema.addConstant(Type.u1, Value.zero); | 15020 | const zero_ov = try sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0)); |
| 14972 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); | 15021 | const no_ov = try block.addBinOp(.cmp_eq, any_ov_bit, zero_ov); |
| 14973 | 15022 | ||
| 14974 | try sema.addSafetyCheck(block, no_ov, .integer_overflow); | 15023 | try sema.addSafetyCheck(block, no_ov, .integer_overflow); |
| ... | @@ -15785,7 +15834,7 @@ fn zirBuiltinSrc( | ... | @@ -15785,7 +15834,7 @@ fn zirBuiltinSrc( |
| 15785 | const name = std.mem.span(fn_owner_decl.name); | 15834 | const name = std.mem.span(fn_owner_decl.name); |
| 15786 | const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]); | 15835 | const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]); |
| 15787 | const new_decl = try anon_decl.finish( | 15836 | const new_decl = try anon_decl.finish( |
| 15788 | try Type.array(anon_decl.arena(), bytes.len - 1, Value.zero, Type.u8, mod), | 15837 | try Type.array(anon_decl.arena(), bytes.len - 1, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 15789 | try Value.Tag.bytes.create(anon_decl.arena(), bytes), | 15838 | try Value.Tag.bytes.create(anon_decl.arena(), bytes), |
| 15790 | 0, // default alignment | 15839 | 0, // default alignment |
| 15791 | ); | 15840 | ); |
| ... | @@ -15798,7 +15847,7 @@ fn zirBuiltinSrc( | ... | @@ -15798,7 +15847,7 @@ fn zirBuiltinSrc( |
| 15798 | // The compiler must not call realpath anywhere. | 15847 | // The compiler must not call realpath anywhere. |
| 15799 | const name = try fn_owner_decl.getFileScope().fullPathZ(anon_decl.arena()); | 15848 | const name = try fn_owner_decl.getFileScope().fullPathZ(anon_decl.arena()); |
| 15800 | const new_decl = try anon_decl.finish( | 15849 | const new_decl = try anon_decl.finish( |
| 15801 | try Type.array(anon_decl.arena(), name.len, Value.zero, Type.u8, mod), | 15850 | try Type.array(anon_decl.arena(), name.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 15802 | try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]), | 15851 | try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]), |
| 15803 | 0, // default alignment | 15852 | 0, // default alignment |
| 15804 | ); | 15853 | ); |
| ... | @@ -16148,7 +16197,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16148,7 +16197,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16148 | defer anon_decl.deinit(); | 16197 | defer anon_decl.deinit(); |
| 16149 | const bytes = try anon_decl.arena().dupeZ(u8, name); | 16198 | const bytes = try anon_decl.arena().dupeZ(u8, name); |
| 16150 | const new_decl = try anon_decl.finish( | 16199 | const new_decl = try anon_decl.finish( |
| 16151 | try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), | 16200 | try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 16152 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), | 16201 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 16153 | 0, // default alignment | 16202 | 0, // default alignment |
| 16154 | ); | 16203 | ); |
| ... | @@ -16256,7 +16305,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16256,7 +16305,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16256 | defer anon_decl.deinit(); | 16305 | defer anon_decl.deinit(); |
| 16257 | const bytes = try anon_decl.arena().dupeZ(u8, name); | 16306 | const bytes = try anon_decl.arena().dupeZ(u8, name); |
| 16258 | const new_decl = try anon_decl.finish( | 16307 | const new_decl = try anon_decl.finish( |
| 16259 | try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), | 16308 | try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 16260 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), | 16309 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 16261 | 0, // default alignment | 16310 | 0, // default alignment |
| 16262 | ); | 16311 | ); |
| ... | @@ -16344,7 +16393,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16344,7 +16393,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16344 | defer anon_decl.deinit(); | 16393 | defer anon_decl.deinit(); |
| 16345 | const bytes = try anon_decl.arena().dupeZ(u8, name); | 16394 | const bytes = try anon_decl.arena().dupeZ(u8, name); |
| 16346 | const new_decl = try anon_decl.finish( | 16395 | const new_decl = try anon_decl.finish( |
| 16347 | try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), | 16396 | try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 16348 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), | 16397 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 16349 | 0, // default alignment | 16398 | 0, // default alignment |
| 16350 | ); | 16399 | ); |
| ... | @@ -16454,7 +16503,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16454,7 +16503,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16454 | else | 16503 | else |
| 16455 | try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i}); | 16504 | try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i}); |
| 16456 | const new_decl = try anon_decl.finish( | 16505 | const new_decl = try anon_decl.finish( |
| 16457 | try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), | 16506 | try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 16458 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), | 16507 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 16459 | 0, // default alignment | 16508 | 0, // default alignment |
| 16460 | ); | 16509 | ); |
| ... | @@ -16496,7 +16545,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -16496,7 +16545,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16496 | defer anon_decl.deinit(); | 16545 | defer anon_decl.deinit(); |
| 16497 | const bytes = try anon_decl.arena().dupeZ(u8, name); | 16546 | const bytes = try anon_decl.arena().dupeZ(u8, name); |
| 16498 | const new_decl = try anon_decl.finish( | 16547 | const new_decl = try anon_decl.finish( |
| 16499 | try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), | 16548 | try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 16500 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), | 16549 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 16501 | 0, // default alignment | 16550 | 0, // default alignment |
| 16502 | ); | 16551 | ); |
| ... | @@ -16692,7 +16741,7 @@ fn typeInfoNamespaceDecls( | ... | @@ -16692,7 +16741,7 @@ fn typeInfoNamespaceDecls( |
| 16692 | defer anon_decl.deinit(); | 16741 | defer anon_decl.deinit(); |
| 16693 | const bytes = try anon_decl.arena().dupeZ(u8, mem.sliceTo(decl.name, 0)); | 16742 | const bytes = try anon_decl.arena().dupeZ(u8, mem.sliceTo(decl.name, 0)); |
| 16694 | const new_decl = try anon_decl.finish( | 16743 | const new_decl = try anon_decl.finish( |
| 16695 | try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), | 16744 | try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 16696 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), | 16745 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 16697 | 0, // default alignment | 16746 | 0, // default alignment |
| 16698 | ); | 16747 | ); |
| ... | @@ -17884,7 +17933,7 @@ fn zirStructInit( | ... | @@ -17884,7 +17933,7 @@ fn zirStructInit( |
| 17884 | } | 17933 | } |
| 17885 | found_fields[field_index] = item.data.field_type; | 17934 | found_fields[field_index] = item.data.field_type; |
| 17886 | field_inits[field_index] = try sema.resolveInst(item.data.init); | 17935 | field_inits[field_index] = try sema.resolveInst(item.data.init); |
| 17887 | if (!is_packed) if (resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| { | 17936 | if (!is_packed) if (try resolved_ty.structFieldValueComptime(mod, field_index)) |default_value| { |
| 17888 | const init_val = (try sema.resolveMaybeUndefVal(field_inits[field_index])) orelse { | 17937 | const init_val = (try sema.resolveMaybeUndefVal(field_inits[field_index])) orelse { |
| 17889 | return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known"); | 17938 | return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime-known"); |
| 17890 | }; | 17939 | }; |
| ... | @@ -18544,8 +18593,8 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -18544,8 +18593,8 @@ fn zirBoolToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 18544 | const operand = try sema.resolveInst(inst_data.operand); | 18593 | const operand = try sema.resolveInst(inst_data.operand); |
| 18545 | if (try sema.resolveMaybeUndefVal(operand)) |val| { | 18594 | if (try sema.resolveMaybeUndefVal(operand)) |val| { |
| 18546 | if (val.isUndef()) return sema.addConstUndef(Type.u1); | 18595 | if (val.isUndef()) return sema.addConstUndef(Type.u1); |
| 18547 | if (val.toBool(mod)) return sema.addConstant(Type.u1, Value.one); | 18596 | if (val.toBool(mod)) return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 1)); |
| 18548 | return sema.addConstant(Type.u1, Value.zero); | 18597 | return sema.addConstant(Type.u1, try mod.intValue(Type.u1, 0)); |
| 18549 | } | 18598 | } |
| 18550 | return block.addUnOp(.bool_to_int, operand); | 18599 | return block.addUnOp(.bool_to_int, operand); |
| 18551 | } | 18600 | } |
| ... | @@ -19761,7 +19810,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -19761,7 +19810,7 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 19761 | const bytes = try ty.nameAllocArena(anon_decl.arena(), mod); | 19810 | const bytes = try ty.nameAllocArena(anon_decl.arena(), mod); |
| 19762 | 19811 | ||
| 19763 | const new_decl = try anon_decl.finish( | 19812 | const new_decl = try anon_decl.finish( |
| 19764 | try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), | 19813 | try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod), |
| 19765 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), | 19814 | try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), |
| 19766 | 0, // default alignment | 19815 | 0, // default alignment |
| 19767 | ); | 19816 | ); |
| ... | @@ -19804,17 +19853,17 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -19804,17 +19853,17 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 19804 | try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); | 19853 | try sema.requireRuntimeBlock(block, inst_data.src(), operand_src); |
| 19805 | if (dest_ty.intInfo(mod).bits == 0) { | 19854 | if (dest_ty.intInfo(mod).bits == 0) { |
| 19806 | if (block.wantSafety()) { | 19855 | if (block.wantSafety()) { |
| 19807 | const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(operand_ty, Value.zero)); | 19856 | const ok = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_eq_optimized else .cmp_eq, operand, try sema.addConstant(operand_ty, try mod.intValue(operand_ty, 0))); |
| 19808 | try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds); | 19857 | try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds); |
| 19809 | } | 19858 | } |
| 19810 | return sema.addConstant(dest_ty, Value.zero); | 19859 | return sema.addConstant(dest_ty, try mod.intValue(dest_ty, 0)); |
| 19811 | } | 19860 | } |
| 19812 | const result = try block.addTyOp(if (block.float_mode == .Optimized) .float_to_int_optimized else .float_to_int, dest_ty, operand); | 19861 | const result = try block.addTyOp(if (block.float_mode == .Optimized) .float_to_int_optimized else .float_to_int, dest_ty, operand); |
| 19813 | if (block.wantSafety()) { | 19862 | if (block.wantSafety()) { |
| 19814 | const back = try block.addTyOp(.int_to_float, operand_ty, result); | 19863 | const back = try block.addTyOp(.int_to_float, operand_ty, result); |
| 19815 | const diff = try block.addBinOp(.sub, operand, back); | 19864 | const diff = try block.addBinOp(.sub, operand, back); |
| 19816 | const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(operand_ty, Value.one)); | 19865 | const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(operand_ty, try mod.intValue(operand_ty, 1))); |
| 19817 | const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(operand_ty, Value.negative_one)); | 19866 | const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(operand_ty, try mod.intValue(operand_ty, -1))); |
| 19818 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); | 19867 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); |
| 19819 | try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds); | 19868 | try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds); |
| 19820 | } | 19869 | } |
| ... | @@ -21398,7 +21447,7 @@ fn analyzeShuffle( | ... | @@ -21398,7 +21447,7 @@ fn analyzeShuffle( |
| 21398 | expand_mask_values[i] = try mod.intValue(Type.comptime_int, i); | 21447 | expand_mask_values[i] = try mod.intValue(Type.comptime_int, i); |
| 21399 | } | 21448 | } |
| 21400 | while (i < max_len) : (i += 1) { | 21449 | while (i < max_len) : (i += 1) { |
| 21401 | expand_mask_values[i] = Value.negative_one; | 21450 | expand_mask_values[i] = try mod.intValue(Type.comptime_int, -1); |
| 21402 | } | 21451 | } |
| 21403 | const expand_mask = try Value.Tag.aggregate.create(sema.arena, expand_mask_values); | 21452 | const expand_mask = try Value.Tag.aggregate.create(sema.arena, expand_mask_values); |
| 21404 | 21453 | ||
| ... | @@ -24504,7 +24553,7 @@ fn finishFieldCallBind( | ... | @@ -24504,7 +24553,7 @@ fn finishFieldCallBind( |
| 24504 | 24553 | ||
| 24505 | const container_ty = ptr_ty.childType(mod); | 24554 | const container_ty = ptr_ty.childType(mod); |
| 24506 | if (container_ty.zigTypeTag(mod) == .Struct) { | 24555 | if (container_ty.zigTypeTag(mod) == .Struct) { |
| 24507 | if (container_ty.structFieldValueComptime(mod, field_index)) |default_val| { | 24556 | if (try container_ty.structFieldValueComptime(mod, field_index)) |default_val| { |
| 24508 | return .{ .direct = try sema.addConstant(field_ty, default_val) }; | 24557 | return .{ .direct = try sema.addConstant(field_ty, default_val) }; |
| 24509 | } | 24558 | } |
| 24510 | } | 24559 | } |
| ... | @@ -24815,7 +24864,7 @@ fn tupleFieldValByIndex( | ... | @@ -24815,7 +24864,7 @@ fn tupleFieldValByIndex( |
| 24815 | const mod = sema.mod; | 24864 | const mod = sema.mod; |
| 24816 | const field_ty = tuple_ty.structFieldType(field_index); | 24865 | const field_ty = tuple_ty.structFieldType(field_index); |
| 24817 | 24866 | ||
| 24818 | if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| { | 24867 | if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| { |
| 24819 | return sema.addConstant(field_ty, default_value); | 24868 | return sema.addConstant(field_ty, default_value); |
| 24820 | } | 24869 | } |
| 24821 | 24870 | ||
| ... | @@ -24828,7 +24877,7 @@ fn tupleFieldValByIndex( | ... | @@ -24828,7 +24877,7 @@ fn tupleFieldValByIndex( |
| 24828 | return sema.addConstant(field_ty, field_values[field_index]); | 24877 | return sema.addConstant(field_ty, field_values[field_index]); |
| 24829 | } | 24878 | } |
| 24830 | 24879 | ||
| 24831 | if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| { | 24880 | if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| { |
| 24832 | return sema.addConstant(field_ty, default_val); | 24881 | return sema.addConstant(field_ty, default_val); |
| 24833 | } | 24882 | } |
| 24834 | 24883 | ||
| ... | @@ -25205,7 +25254,7 @@ fn tupleFieldPtr( | ... | @@ -25205,7 +25254,7 @@ fn tupleFieldPtr( |
| 25205 | .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod), | 25254 | .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod), |
| 25206 | }); | 25255 | }); |
| 25207 | 25256 | ||
| 25208 | if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| { | 25257 | if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| { |
| 25209 | const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{ | 25258 | const val = try Value.Tag.comptime_field_ptr.create(sema.arena, .{ |
| 25210 | .field_ty = field_ty, | 25259 | .field_ty = field_ty, |
| 25211 | .field_val = default_val, | 25260 | .field_val = default_val, |
| ... | @@ -25256,13 +25305,13 @@ fn tupleField( | ... | @@ -25256,13 +25305,13 @@ fn tupleField( |
| 25256 | 25305 | ||
| 25257 | const field_ty = tuple_ty.structFieldType(field_index); | 25306 | const field_ty = tuple_ty.structFieldType(field_index); |
| 25258 | 25307 | ||
| 25259 | if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| { | 25308 | if (try tuple_ty.structFieldValueComptime(mod, field_index)) |default_value| { |
| 25260 | return sema.addConstant(field_ty, default_value); // comptime field | 25309 | return sema.addConstant(field_ty, default_value); // comptime field |
| 25261 | } | 25310 | } |
| 25262 | 25311 | ||
| 25263 | if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| { | 25312 | if (try sema.resolveMaybeUndefVal(tuple)) |tuple_val| { |
| 25264 | if (tuple_val.isUndef()) return sema.addConstUndef(field_ty); | 25313 | if (tuple_val.isUndef()) return sema.addConstUndef(field_ty); |
| 25265 | return sema.addConstant(field_ty, tuple_val.fieldValue(tuple_ty, mod, field_index)); | 25314 | return sema.addConstant(field_ty, try tuple_val.fieldValue(tuple_ty, mod, field_index)); |
| 25266 | } | 25315 | } |
| 25267 | 25316 | ||
| 25268 | try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src); | 25317 | try sema.validateRuntimeElemAccess(block, field_index_src, field_ty, tuple_ty, tuple_src); |
| ... | @@ -25812,7 +25861,7 @@ fn coerceExtra( | ... | @@ -25812,7 +25861,7 @@ fn coerceExtra( |
| 25812 | if (inst_info.size == .Slice) { | 25861 | if (inst_info.size == .Slice) { |
| 25813 | assert(dest_info.sentinel == null); | 25862 | assert(dest_info.sentinel == null); |
| 25814 | if (inst_info.sentinel == null or | 25863 | if (inst_info.sentinel == null or |
| 25815 | !inst_info.sentinel.?.eql(Value.zero, dest_info.pointee_type, sema.mod)) | 25864 | !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, sema.mod)) |
| 25816 | break :p; | 25865 | break :p; |
| 25817 | 25866 | ||
| 25818 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); | 25867 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | @@ -25879,7 +25928,7 @@ fn coerceExtra( | ... | @@ -25879,7 +25928,7 @@ fn coerceExtra( |
| 25879 | try mod.intValue(Type.usize, dest_info.@"align") | 25928 | try mod.intValue(Type.usize, dest_info.@"align") |
| 25880 | else | 25929 | else |
| 25881 | try dest_info.pointee_type.lazyAbiAlignment(mod, sema.arena), | 25930 | try dest_info.pointee_type.lazyAbiAlignment(mod, sema.arena), |
| 25882 | .len = Value.zero, | 25931 | .len = try mod.intValue(Type.usize, 0), |
| 25883 | }); | 25932 | }); |
| 25884 | return sema.addConstant(dest_ty, slice_val); | 25933 | return sema.addConstant(dest_ty, slice_val); |
| 25885 | } | 25934 | } |
| ... | @@ -28234,7 +28283,7 @@ fn beginComptimePtrLoad( | ... | @@ -28234,7 +28283,7 @@ fn beginComptimePtrLoad( |
| 28234 | const field_ty = field_ptr.container_ty.structFieldType(field_index); | 28283 | const field_ty = field_ptr.container_ty.structFieldType(field_index); |
| 28235 | deref.pointee = TypedValue{ | 28284 | deref.pointee = TypedValue{ |
| 28236 | .ty = field_ty, | 28285 | .ty = field_ty, |
| 28237 | .val = tv.val.fieldValue(tv.ty, mod, field_index), | 28286 | .val = try tv.val.fieldValue(tv.ty, mod, field_index), |
| 28238 | }; | 28287 | }; |
| 28239 | } | 28288 | } |
| 28240 | break :blk deref; | 28289 | break :blk deref; |
| ... | @@ -32532,9 +32581,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { | ... | @@ -32532,9 +32581,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { |
| 32532 | break :blk try val.copy(decl_arena_allocator); | 32581 | break :blk try val.copy(decl_arena_allocator); |
| 32533 | } else blk: { | 32582 | } else blk: { |
| 32534 | const val = if (last_tag_val) |val| | 32583 | const val = if (last_tag_val) |val| |
| 32535 | try sema.intAdd(val, Value.one, int_tag_ty) | 32584 | try sema.intAdd(val, try mod.intValue(int_tag_ty, 1), int_tag_ty) |
| 32536 | else | 32585 | else |
| 32537 | Value.zero; | 32586 | try mod.intValue(int_tag_ty, 0); |
| 32538 | last_tag_val = val; | 32587 | last_tag_val = val; |
| 32539 | 32588 | ||
| 32540 | break :blk try val.copy(decl_arena_allocator); | 32589 | break :blk try val.copy(decl_arena_allocator); |
| ... | @@ -32903,7 +32952,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -32903,7 +32952,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 32903 | if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 32952 | if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 32904 | .int_type => |int_type| { | 32953 | .int_type => |int_type| { |
| 32905 | if (int_type.bits == 0) { | 32954 | if (int_type.bits == 0) { |
| 32906 | return Value.zero; | 32955 | return try mod.intValue(ty, 0); |
| 32907 | } else { | 32956 | } else { |
| 32908 | return null; | 32957 | return null; |
| 32909 | } | 32958 | } |
| ... | @@ -33049,7 +33098,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33049,7 +33098,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33049 | } | 33098 | } |
| 33050 | if (enum_obj.fields.count() == 1) { | 33099 | if (enum_obj.fields.count() == 1) { |
| 33051 | if (enum_obj.values.count() == 0) { | 33100 | if (enum_obj.values.count() == 0) { |
| 33052 | return Value.zero; // auto-numbered | 33101 | return try mod.intValue(ty, 0); // auto-numbered |
| 33053 | } else { | 33102 | } else { |
| 33054 | return enum_obj.values.keys()[0]; | 33103 | return enum_obj.values.keys()[0]; |
| 33055 | } | 33104 | } |
| ... | @@ -33066,7 +33115,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33066,7 +33115,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33066 | switch (enum_obj.fields.count()) { | 33115 | switch (enum_obj.fields.count()) { |
| 33067 | 0 => return Value.@"unreachable", | 33116 | 0 => return Value.@"unreachable", |
| 33068 | 1 => if (enum_obj.values.count() == 0) { | 33117 | 1 => if (enum_obj.values.count() == 0) { |
| 33069 | return Value.zero; // auto-numbered | 33118 | return try mod.intValue(ty, 0); // auto-numbered |
| 33070 | } else { | 33119 | } else { |
| 33071 | return enum_obj.values.keys()[0]; | 33120 | return enum_obj.values.keys()[0]; |
| 33072 | }, | 33121 | }, |
| ... | @@ -33078,14 +33127,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { | ... | @@ -33078,14 +33127,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { |
| 33078 | const enum_simple = resolved_ty.castTag(.enum_simple).?.data; | 33127 | const enum_simple = resolved_ty.castTag(.enum_simple).?.data; |
| 33079 | switch (enum_simple.fields.count()) { | 33128 | switch (enum_simple.fields.count()) { |
| 33080 | 0 => return Value.@"unreachable", | 33129 | 0 => return Value.@"unreachable", |
| 33081 | 1 => return Value.zero, | 33130 | 1 => return try mod.intValue(ty, 0), |
| 33082 | else => return null, | 33131 | else => return null, |
| 33083 | } | 33132 | } |
| 33084 | }, | 33133 | }, |
| 33085 | .enum_nonexhaustive => { | 33134 | .enum_nonexhaustive => { |
| 33086 | const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty; | 33135 | const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty; |
| 33087 | if (tag_ty.zigTypeTag(mod) != .ComptimeInt and !(try sema.typeHasRuntimeBits(tag_ty))) { | 33136 | if (tag_ty.zigTypeTag(mod) != .ComptimeInt and !(try sema.typeHasRuntimeBits(tag_ty))) { |
| 33088 | return Value.zero; | 33137 | return try mod.intValue(ty, 0); |
| 33089 | } else { | 33138 | } else { |
| 33090 | return null; | 33139 | return null; |
| 33091 | } | 33140 | } |
src/TypedValue.zig+8-5| ... | @@ -61,7 +61,10 @@ pub fn format( | ... | @@ -61,7 +61,10 @@ pub fn format( |
| 61 | ) !void { | 61 | ) !void { |
| 62 | _ = options; | 62 | _ = options; |
| 63 | comptime std.debug.assert(fmt.len == 0); | 63 | comptime std.debug.assert(fmt.len == 0); |
| 64 | return ctx.tv.print(writer, 3, ctx.mod); | 64 | return ctx.tv.print(writer, 3, ctx.mod) catch |err| switch (err) { |
| 65 | error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function | ||
| 66 | else => |e| return e, | ||
| 67 | }; | ||
| 65 | } | 68 | } |
| 66 | 69 | ||
| 67 | /// Prints the Value according to the Type, not according to the Value Tag. | 70 | /// Prints the Value according to the Type, not according to the Value Tag. |
| ... | @@ -70,7 +73,7 @@ pub fn print( | ... | @@ -70,7 +73,7 @@ pub fn print( |
| 70 | writer: anytype, | 73 | writer: anytype, |
| 71 | level: u8, | 74 | level: u8, |
| 72 | mod: *Module, | 75 | mod: *Module, |
| 73 | ) @TypeOf(writer).Error!void { | 76 | ) (@TypeOf(writer).Error || Allocator.Error)!void { |
| 74 | var val = tv.val; | 77 | var val = tv.val; |
| 75 | var ty = tv.ty; | 78 | var ty = tv.ty; |
| 76 | if (val.isVariable(mod)) | 79 | if (val.isVariable(mod)) |
| ... | @@ -95,7 +98,7 @@ pub fn print( | ... | @@ -95,7 +98,7 @@ pub fn print( |
| 95 | } | 98 | } |
| 96 | try print(.{ | 99 | try print(.{ |
| 97 | .ty = ty.structFieldType(i), | 100 | .ty = ty.structFieldType(i), |
| 98 | .val = val.fieldValue(ty, mod, i), | 101 | .val = try val.fieldValue(ty, mod, i), |
| 99 | }, writer, level - 1, mod); | 102 | }, writer, level - 1, mod); |
| 100 | } | 103 | } |
| 101 | if (ty.structFieldCount() > max_aggregate_items) { | 104 | if (ty.structFieldCount() > max_aggregate_items) { |
| ... | @@ -112,7 +115,7 @@ pub fn print( | ... | @@ -112,7 +115,7 @@ pub fn print( |
| 112 | 115 | ||
| 113 | var i: u32 = 0; | 116 | var i: u32 = 0; |
| 114 | while (i < max_len) : (i += 1) { | 117 | while (i < max_len) : (i += 1) { |
| 115 | const elem = val.fieldValue(ty, mod, i); | 118 | const elem = try val.fieldValue(ty, mod, i); |
| 116 | if (elem.isUndef()) break :str; | 119 | if (elem.isUndef()) break :str; |
| 117 | buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str; | 120 | buf[i] = std.math.cast(u8, elem.toUnsignedInt(mod)) orelse break :str; |
| 118 | } | 121 | } |
| ... | @@ -129,7 +132,7 @@ pub fn print( | ... | @@ -129,7 +132,7 @@ pub fn print( |
| 129 | if (i != 0) try writer.writeAll(", "); | 132 | if (i != 0) try writer.writeAll(", "); |
| 130 | try print(.{ | 133 | try print(.{ |
| 131 | .ty = elem_ty, | 134 | .ty = elem_ty, |
| 132 | .val = val.fieldValue(ty, mod, i), | 135 | .val = try val.fieldValue(ty, mod, i), |
| 133 | }, writer, level - 1, mod); | 136 | }, writer, level - 1, mod); |
| 134 | } | 137 | } |
| 135 | if (len > max_aggregate_items) { | 138 | if (len > max_aggregate_items) { |
src/arch/aarch64/CodeGen.zig+2-2| ... | @@ -4311,7 +4311,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4311,7 +4311,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4311 | 4311 | ||
| 4312 | // Due to incremental compilation, how function calls are generated depends | 4312 | // Due to incremental compilation, how function calls are generated depends |
| 4313 | // on linking. | 4313 | // on linking. |
| 4314 | if (self.air.value(callee, mod)) |func_value| { | 4314 | if (try self.air.value(callee, mod)) |func_value| { |
| 4315 | if (func_value.castTag(.function)) |func_payload| { | 4315 | if (func_value.castTag(.function)) |func_payload| { |
| 4316 | const func = func_payload.data; | 4316 | const func = func_payload.data; |
| 4317 | 4317 | ||
| ... | @@ -6154,7 +6154,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -6154,7 +6154,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 6154 | 6154 | ||
| 6155 | const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{ | 6155 | const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{ |
| 6156 | .ty = inst_ty, | 6156 | .ty = inst_ty, |
| 6157 | .val = self.air.value(inst, mod).?, | 6157 | .val = (try self.air.value(inst, mod)).?, |
| 6158 | }); | 6158 | }); |
| 6159 | 6159 | ||
| 6160 | switch (self.air.instructions.items(.tag)[inst_index]) { | 6160 | switch (self.air.instructions.items(.tag)[inst_index]) { |
src/arch/arm/CodeGen.zig+2-2| ... | @@ -4291,7 +4291,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -4291,7 +4291,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 4291 | 4291 | ||
| 4292 | // Due to incremental compilation, how function calls are generated depends | 4292 | // Due to incremental compilation, how function calls are generated depends |
| 4293 | // on linking. | 4293 | // on linking. |
| 4294 | if (self.air.value(callee, mod)) |func_value| { | 4294 | if (try self.air.value(callee, mod)) |func_value| { |
| 4295 | if (func_value.castTag(.function)) |func_payload| { | 4295 | if (func_value.castTag(.function)) |func_payload| { |
| 4296 | const func = func_payload.data; | 4296 | const func = func_payload.data; |
| 4297 | 4297 | ||
| ... | @@ -6101,7 +6101,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -6101,7 +6101,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 6101 | 6101 | ||
| 6102 | const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{ | 6102 | const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{ |
| 6103 | .ty = inst_ty, | 6103 | .ty = inst_ty, |
| 6104 | .val = self.air.value(inst, mod).?, | 6104 | .val = (try self.air.value(inst, mod)).?, |
| 6105 | }); | 6105 | }); |
| 6106 | 6106 | ||
| 6107 | switch (self.air.instructions.items(.tag)[inst_index]) { | 6107 | switch (self.air.instructions.items(.tag)[inst_index]) { |
src/arch/riscv64/CodeGen.zig+2-2| ... | @@ -1743,7 +1743,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -1743,7 +1743,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 1743 | } | 1743 | } |
| 1744 | } | 1744 | } |
| 1745 | 1745 | ||
| 1746 | if (self.air.value(callee, mod)) |func_value| { | 1746 | if (try self.air.value(callee, mod)) |func_value| { |
| 1747 | if (func_value.castTag(.function)) |func_payload| { | 1747 | if (func_value.castTag(.function)) |func_payload| { |
| 1748 | const func = func_payload.data; | 1748 | const func = func_payload.data; |
| 1749 | const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); | 1749 | const atom_index = try elf_file.getOrCreateAtomForDecl(func.owner_decl); |
| ... | @@ -2551,7 +2551,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -2551,7 +2551,7 @@ fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue { |
| 2551 | 2551 | ||
| 2552 | const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{ | 2552 | const inst_index = Air.refToIndex(inst) orelse return self.genTypedValue(.{ |
| 2553 | .ty = inst_ty, | 2553 | .ty = inst_ty, |
| 2554 | .val = self.air.value(inst, mod).?, | 2554 | .val = (try self.air.value(inst, mod)).?, |
| 2555 | }); | 2555 | }); |
| 2556 | 2556 | ||
| 2557 | switch (self.air.instructions.items(.tag)[inst_index]) { | 2557 | switch (self.air.instructions.items(.tag)[inst_index]) { |
src/arch/sparc64/CodeGen.zig+2-2| ... | @@ -1343,7 +1343,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -1343,7 +1343,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 1343 | 1343 | ||
| 1344 | // Due to incremental compilation, how function calls are generated depends | 1344 | // Due to incremental compilation, how function calls are generated depends |
| 1345 | // on linking. | 1345 | // on linking. |
| 1346 | if (self.air.value(callee, mod)) |func_value| { | 1346 | if (try self.air.value(callee, mod)) |func_value| { |
| 1347 | if (self.bin_file.tag == link.File.Elf.base_tag) { | 1347 | if (self.bin_file.tag == link.File.Elf.base_tag) { |
| 1348 | if (func_value.castTag(.function)) |func_payload| { | 1348 | if (func_value.castTag(.function)) |func_payload| { |
| 1349 | const func = func_payload.data; | 1349 | const func = func_payload.data; |
| ... | @@ -4575,7 +4575,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -4575,7 +4575,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 4575 | 4575 | ||
| 4576 | return self.genTypedValue(.{ | 4576 | return self.genTypedValue(.{ |
| 4577 | .ty = ty, | 4577 | .ty = ty, |
| 4578 | .val = self.air.value(ref, mod).?, | 4578 | .val = (try self.air.value(ref, mod)).?, |
| 4579 | }); | 4579 | }); |
| 4580 | } | 4580 | } |
| 4581 | 4581 |
src/arch/wasm/CodeGen.zig+5-5| ... | @@ -789,7 +789,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { | ... | @@ -789,7 +789,7 @@ fn resolveInst(func: *CodeGen, ref: Air.Inst.Ref) InnerError!WValue { |
| 789 | assert(!gop.found_existing); | 789 | assert(!gop.found_existing); |
| 790 | 790 | ||
| 791 | const mod = func.bin_file.base.options.module.?; | 791 | const mod = func.bin_file.base.options.module.?; |
| 792 | const val = func.air.value(ref, mod).?; | 792 | const val = (try func.air.value(ref, mod)).?; |
| 793 | const ty = func.typeOf(ref); | 793 | const ty = func.typeOf(ref); |
| 794 | if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) { | 794 | if (!ty.hasRuntimeBitsIgnoreComptime(mod) and !ty.isInt(mod) and !ty.isError(mod)) { |
| 795 | gop.value_ptr.* = WValue{ .none = {} }; | 795 | gop.value_ptr.* = WValue{ .none = {} }; |
| ... | @@ -2195,7 +2195,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif | ... | @@ -2195,7 +2195,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 2195 | const first_param_sret = firstParamSRet(fn_info.cc, fn_info.return_type, mod); | 2195 | const first_param_sret = firstParamSRet(fn_info.cc, fn_info.return_type, mod); |
| 2196 | 2196 | ||
| 2197 | const callee: ?Decl.Index = blk: { | 2197 | const callee: ?Decl.Index = blk: { |
| 2198 | const func_val = func.air.value(pl_op.operand, mod) orelse break :blk null; | 2198 | const func_val = (try func.air.value(pl_op.operand, mod)) orelse break :blk null; |
| 2199 | 2199 | ||
| 2200 | if (func_val.castTag(.function)) |function| { | 2200 | if (func_val.castTag(.function)) |function| { |
| 2201 | _ = try func.bin_file.getOrCreateAtomForDecl(function.data.owner_decl); | 2201 | _ = try func.bin_file.getOrCreateAtomForDecl(function.data.owner_decl); |
| ... | @@ -3138,7 +3138,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { | ... | @@ -3138,7 +3138,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { |
| 3138 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { | 3138 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3139 | // We use the error type directly as the type. | 3139 | // We use the error type directly as the type. |
| 3140 | const is_pl = val.errorUnionIsPayload(); | 3140 | const is_pl = val.errorUnionIsPayload(); |
| 3141 | const err_val = if (!is_pl) val else Value.zero; | 3141 | const err_val = if (!is_pl) val else try mod.intValue(error_type, 0); |
| 3142 | return func.lowerConstant(err_val, error_type); | 3142 | return func.lowerConstant(err_val, error_type); |
| 3143 | } | 3143 | } |
| 3144 | return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{}); | 3144 | return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{}); |
| ... | @@ -3792,7 +3792,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -3792,7 +3792,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 3792 | errdefer func.gpa.free(values); | 3792 | errdefer func.gpa.free(values); |
| 3793 | 3793 | ||
| 3794 | for (items, 0..) |ref, i| { | 3794 | for (items, 0..) |ref, i| { |
| 3795 | const item_val = func.air.value(ref, mod).?; | 3795 | const item_val = (try func.air.value(ref, mod)).?; |
| 3796 | const int_val = func.valueAsI32(item_val, target_ty); | 3796 | const int_val = func.valueAsI32(item_val, target_ty); |
| 3797 | if (lowest_maybe == null or int_val < lowest_maybe.?) { | 3797 | if (lowest_maybe == null or int_val < lowest_maybe.?) { |
| 3798 | lowest_maybe = int_val; | 3798 | lowest_maybe = int_val; |
| ... | @@ -5048,7 +5048,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5048,7 +5048,7 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5048 | const result = try func.allocStack(result_ty); | 5048 | const result = try func.allocStack(result_ty); |
| 5049 | const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset | 5049 | const offset = try func.buildPointerOffset(result, 0, .new); // pointer to offset |
| 5050 | for (elements, 0..) |elem, elem_index| { | 5050 | for (elements, 0..) |elem, elem_index| { |
| 5051 | if (result_ty.structFieldValueComptime(mod, elem_index) != null) continue; | 5051 | if ((try result_ty.structFieldValueComptime(mod, elem_index)) != null) continue; |
| 5052 | 5052 | ||
| 5053 | const elem_ty = result_ty.structFieldType(elem_index); | 5053 | const elem_ty = result_ty.structFieldType(elem_index); |
| 5054 | const elem_size = @intCast(u32, elem_ty.abiSize(mod)); | 5054 | const elem_size = @intCast(u32, elem_ty.abiSize(mod)); |
src/arch/x86_64/CodeGen.zig+6-6| ... | @@ -2768,7 +2768,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -2768,7 +2768,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { |
| 2768 | 2768 | ||
| 2769 | const full_ty = try mod.vectorType(.{ | 2769 | const full_ty = try mod.vectorType(.{ |
| 2770 | .len = @intCast(u32, @divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)), | 2770 | .len = @intCast(u32, @divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)), |
| 2771 | .child = src_ty.childType(mod).ip_index, | 2771 | .child = elem_ty.ip_index, |
| 2772 | }); | 2772 | }); |
| 2773 | const full_abi_size = @intCast(u32, full_ty.abiSize(mod)); | 2773 | const full_abi_size = @intCast(u32, full_ty.abiSize(mod)); |
| 2774 | 2774 | ||
| ... | @@ -8107,7 +8107,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier | ... | @@ -8107,7 +8107,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier |
| 8107 | 8107 | ||
| 8108 | // Due to incremental compilation, how function calls are generated depends | 8108 | // Due to incremental compilation, how function calls are generated depends |
| 8109 | // on linking. | 8109 | // on linking. |
| 8110 | if (self.air.value(callee, mod)) |func_value| { | 8110 | if (try self.air.value(callee, mod)) |func_value| { |
| 8111 | if (if (func_value.castTag(.function)) |func_payload| | 8111 | if (if (func_value.castTag(.function)) |func_payload| |
| 8112 | func_payload.data.owner_decl | 8112 | func_payload.data.owner_decl |
| 8113 | else if (func_value.castTag(.decl_ref)) |decl_ref_payload| | 8113 | else if (func_value.castTag(.decl_ref)) |decl_ref_payload| |
| ... | @@ -11265,7 +11265,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11265,7 +11265,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 11265 | .{ .immediate = result_ty.abiSize(mod) }, | 11265 | .{ .immediate = result_ty.abiSize(mod) }, |
| 11266 | ); | 11266 | ); |
| 11267 | for (elements, 0..) |elem, elem_i| { | 11267 | for (elements, 0..) |elem, elem_i| { |
| 11268 | if (result_ty.structFieldValueComptime(mod, elem_i) != null) continue; | 11268 | if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue; |
| 11269 | 11269 | ||
| 11270 | const elem_ty = result_ty.structFieldType(elem_i); | 11270 | const elem_ty = result_ty.structFieldType(elem_i); |
| 11271 | const elem_bit_size = @intCast(u32, elem_ty.bitSize(mod)); | 11271 | const elem_bit_size = @intCast(u32, elem_ty.bitSize(mod)); |
| ... | @@ -11337,7 +11337,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { | ... | @@ -11337,7 +11337,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { |
| 11337 | } | 11337 | } |
| 11338 | } | 11338 | } |
| 11339 | } else for (elements, 0..) |elem, elem_i| { | 11339 | } else for (elements, 0..) |elem, elem_i| { |
| 11340 | if (result_ty.structFieldValueComptime(mod, elem_i) != null) continue; | 11340 | if ((try result_ty.structFieldValueComptime(mod, elem_i)) != null) continue; |
| 11341 | 11341 | ||
| 11342 | const elem_ty = result_ty.structFieldType(elem_i); | 11342 | const elem_ty = result_ty.structFieldType(elem_i); |
| 11343 | const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, mod)); | 11343 | const elem_off = @intCast(i32, result_ty.structFieldOffset(elem_i, mod)); |
| ... | @@ -11601,7 +11601,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -11601,7 +11601,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 11601 | const gop = try self.const_tracking.getOrPut(self.gpa, inst); | 11601 | const gop = try self.const_tracking.getOrPut(self.gpa, inst); |
| 11602 | if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{ | 11602 | if (!gop.found_existing) gop.value_ptr.* = InstTracking.init(try self.genTypedValue(.{ |
| 11603 | .ty = ty, | 11603 | .ty = ty, |
| 11604 | .val = self.air.value(ref, mod).?, | 11604 | .val = (try self.air.value(ref, mod)).?, |
| 11605 | })); | 11605 | })); |
| 11606 | break :tracking gop.value_ptr; | 11606 | break :tracking gop.value_ptr; |
| 11607 | }, | 11607 | }, |
| ... | @@ -11614,7 +11614,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { | ... | @@ -11614,7 +11614,7 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue { |
| 11614 | } | 11614 | } |
| 11615 | } | 11615 | } |
| 11616 | 11616 | ||
| 11617 | return self.genTypedValue(.{ .ty = ty, .val = self.air.value(ref, mod).? }); | 11617 | return self.genTypedValue(.{ .ty = ty, .val = (try self.air.value(ref, mod)).? }); |
| 11618 | } | 11618 | } |
| 11619 | 11619 | ||
| 11620 | fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking { | 11620 | fn getResolvedInstValue(self: *Self, inst: Air.Inst.Index) *InstTracking { |
src/codegen.zig+4-4| ... | @@ -675,7 +675,7 @@ pub fn generateSymbol( | ... | @@ -675,7 +675,7 @@ pub fn generateSymbol( |
| 675 | const is_payload = typed_value.val.errorUnionIsPayload(); | 675 | const is_payload = typed_value.val.errorUnionIsPayload(); |
| 676 | 676 | ||
| 677 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 677 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 678 | const err_val = if (is_payload) Value.zero else typed_value.val; | 678 | const err_val = if (is_payload) try mod.intValue(error_ty, 0) else typed_value.val; |
| 679 | return generateSymbol(bin_file, src_loc, .{ | 679 | return generateSymbol(bin_file, src_loc, .{ |
| 680 | .ty = error_ty, | 680 | .ty = error_ty, |
| 681 | .val = err_val, | 681 | .val = err_val, |
| ... | @@ -690,7 +690,7 @@ pub fn generateSymbol( | ... | @@ -690,7 +690,7 @@ pub fn generateSymbol( |
| 690 | if (error_align > payload_align) { | 690 | if (error_align > payload_align) { |
| 691 | switch (try generateSymbol(bin_file, src_loc, .{ | 691 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 692 | .ty = error_ty, | 692 | .ty = error_ty, |
| 693 | .val = if (is_payload) Value.zero else typed_value.val, | 693 | .val = if (is_payload) try mod.intValue(error_ty, 0) else typed_value.val, |
| 694 | }, code, debug_output, reloc_info)) { | 694 | }, code, debug_output, reloc_info)) { |
| 695 | .ok => {}, | 695 | .ok => {}, |
| 696 | .fail => |em| return Result{ .fail = em }, | 696 | .fail => |em| return Result{ .fail = em }, |
| ... | @@ -722,7 +722,7 @@ pub fn generateSymbol( | ... | @@ -722,7 +722,7 @@ pub fn generateSymbol( |
| 722 | const begin = code.items.len; | 722 | const begin = code.items.len; |
| 723 | switch (try generateSymbol(bin_file, src_loc, .{ | 723 | switch (try generateSymbol(bin_file, src_loc, .{ |
| 724 | .ty = error_ty, | 724 | .ty = error_ty, |
| 725 | .val = if (is_payload) Value.zero else typed_value.val, | 725 | .val = if (is_payload) try mod.intValue(error_ty, 0) else typed_value.val, |
| 726 | }, code, debug_output, reloc_info)) { | 726 | }, code, debug_output, reloc_info)) { |
| 727 | .ok => {}, | 727 | .ok => {}, |
| 728 | .fail => |em| return Result{ .fail = em }, | 728 | .fail => |em| return Result{ .fail = em }, |
| ... | @@ -1280,7 +1280,7 @@ pub fn genTypedValue( | ... | @@ -1280,7 +1280,7 @@ pub fn genTypedValue( |
| 1280 | 1280 | ||
| 1281 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { | 1281 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { |
| 1282 | // We use the error type directly as the type. | 1282 | // We use the error type directly as the type. |
| 1283 | const err_val = if (!is_pl) typed_value.val else Value.zero; | 1283 | const err_val = if (!is_pl) typed_value.val else try mod.intValue(error_type, 0); |
| 1284 | return genTypedValue(bin_file, src_loc, .{ | 1284 | return genTypedValue(bin_file, src_loc, .{ |
| 1285 | .ty = error_type, | 1285 | .ty = error_type, |
| 1286 | .val = err_val, | 1286 | .val = err_val, |
src/codegen/c.zig+32-32| ... | @@ -287,7 +287,7 @@ pub const Function = struct { | ... | @@ -287,7 +287,7 @@ pub const Function = struct { |
| 287 | if (gop.found_existing) return gop.value_ptr.*; | 287 | if (gop.found_existing) return gop.value_ptr.*; |
| 288 | 288 | ||
| 289 | const mod = f.object.dg.module; | 289 | const mod = f.object.dg.module; |
| 290 | const val = f.air.value(ref, mod).?; | 290 | const val = (try f.air.value(ref, mod)).?; |
| 291 | const ty = f.typeOf(ref); | 291 | const ty = f.typeOf(ref); |
| 292 | 292 | ||
| 293 | const result: CValue = if (lowersToArray(ty, mod)) result: { | 293 | const result: CValue = if (lowersToArray(ty, mod)) result: { |
| ... | @@ -356,7 +356,7 @@ pub const Function = struct { | ... | @@ -356,7 +356,7 @@ pub const Function = struct { |
| 356 | .constant => |inst| { | 356 | .constant => |inst| { |
| 357 | const mod = f.object.dg.module; | 357 | const mod = f.object.dg.module; |
| 358 | const ty = f.typeOf(inst); | 358 | const ty = f.typeOf(inst); |
| 359 | const val = f.air.value(inst, mod).?; | 359 | const val = (try f.air.value(inst, mod)).?; |
| 360 | return f.object.dg.renderValue(w, ty, val, location); | 360 | return f.object.dg.renderValue(w, ty, val, location); |
| 361 | }, | 361 | }, |
| 362 | .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location), | 362 | .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location), |
| ... | @@ -369,7 +369,7 @@ pub const Function = struct { | ... | @@ -369,7 +369,7 @@ pub const Function = struct { |
| 369 | .constant => |inst| { | 369 | .constant => |inst| { |
| 370 | const mod = f.object.dg.module; | 370 | const mod = f.object.dg.module; |
| 371 | const ty = f.typeOf(inst); | 371 | const ty = f.typeOf(inst); |
| 372 | const val = f.air.value(inst, mod).?; | 372 | const val = (try f.air.value(inst, mod)).?; |
| 373 | try w.writeAll("(*"); | 373 | try w.writeAll("(*"); |
| 374 | try f.object.dg.renderValue(w, ty, val, .Other); | 374 | try f.object.dg.renderValue(w, ty, val, .Other); |
| 375 | return w.writeByte(')'); | 375 | return w.writeByte(')'); |
| ... | @@ -383,7 +383,7 @@ pub const Function = struct { | ... | @@ -383,7 +383,7 @@ pub const Function = struct { |
| 383 | .constant => |inst| { | 383 | .constant => |inst| { |
| 384 | const mod = f.object.dg.module; | 384 | const mod = f.object.dg.module; |
| 385 | const ty = f.typeOf(inst); | 385 | const ty = f.typeOf(inst); |
| 386 | const val = f.air.value(inst, mod).?; | 386 | const val = (try f.air.value(inst, mod)).?; |
| 387 | try f.object.dg.renderValue(w, ty, val, .Other); | 387 | try f.object.dg.renderValue(w, ty, val, .Other); |
| 388 | try w.writeByte('.'); | 388 | try w.writeByte('.'); |
| 389 | return f.writeCValue(w, member, .Other); | 389 | return f.writeCValue(w, member, .Other); |
| ... | @@ -397,7 +397,7 @@ pub const Function = struct { | ... | @@ -397,7 +397,7 @@ pub const Function = struct { |
| 397 | .constant => |inst| { | 397 | .constant => |inst| { |
| 398 | const mod = f.object.dg.module; | 398 | const mod = f.object.dg.module; |
| 399 | const ty = f.typeOf(inst); | 399 | const ty = f.typeOf(inst); |
| 400 | const val = f.air.value(inst, mod).?; | 400 | const val = (try f.air.value(inst, mod)).?; |
| 401 | try w.writeByte('('); | 401 | try w.writeByte('('); |
| 402 | try f.object.dg.renderValue(w, ty, val, .Other); | 402 | try f.object.dg.renderValue(w, ty, val, .Other); |
| 403 | try w.writeAll(")->"); | 403 | try w.writeAll(")->"); |
| ... | @@ -690,7 +690,7 @@ pub const DeclGen = struct { | ... | @@ -690,7 +690,7 @@ pub const DeclGen = struct { |
| 690 | location, | 690 | location, |
| 691 | ); | 691 | ); |
| 692 | try writer.print(") + {})", .{ | 692 | try writer.print(") + {})", .{ |
| 693 | try dg.fmtIntLiteral(Type.usize, Value.one, .Other), | 693 | try dg.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1), .Other), |
| 694 | }); | 694 | }); |
| 695 | }, | 695 | }, |
| 696 | } | 696 | } |
| ... | @@ -1253,7 +1253,7 @@ pub const DeclGen = struct { | ... | @@ -1253,7 +1253,7 @@ pub const DeclGen = struct { |
| 1253 | .ErrorUnion => { | 1253 | .ErrorUnion => { |
| 1254 | const payload_ty = ty.errorUnionPayload(); | 1254 | const payload_ty = ty.errorUnionPayload(); |
| 1255 | const error_ty = ty.errorUnionSet(); | 1255 | const error_ty = ty.errorUnionSet(); |
| 1256 | const error_val = if (val.errorUnionIsPayload()) Value.zero else val; | 1256 | const error_val = if (val.errorUnionIsPayload()) try mod.intValue(Type.anyerror, 0) else val; |
| 1257 | 1257 | ||
| 1258 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 1258 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 1259 | return dg.renderValue(writer, error_ty, error_val, location); | 1259 | return dg.renderValue(writer, error_ty, error_val, location); |
| ... | @@ -3611,7 +3611,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -3611,7 +3611,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 3611 | const ptr_val = try f.resolveInst(bin_op.lhs); | 3611 | const ptr_val = try f.resolveInst(bin_op.lhs); |
| 3612 | const src_ty = f.typeOf(bin_op.rhs); | 3612 | const src_ty = f.typeOf(bin_op.rhs); |
| 3613 | 3613 | ||
| 3614 | const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false; | 3614 | const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |v| v.isUndefDeep() else false; |
| 3615 | 3615 | ||
| 3616 | if (val_is_undef) { | 3616 | if (val_is_undef) { |
| 3617 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); | 3617 | try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); |
| ... | @@ -4183,7 +4183,7 @@ fn airCall( | ... | @@ -4183,7 +4183,7 @@ fn airCall( |
| 4183 | callee: { | 4183 | callee: { |
| 4184 | known: { | 4184 | known: { |
| 4185 | const fn_decl = fn_decl: { | 4185 | const fn_decl = fn_decl: { |
| 4186 | const callee_val = f.air.value(pl_op.operand, mod) orelse break :known; | 4186 | const callee_val = (try f.air.value(pl_op.operand, mod)) orelse break :known; |
| 4187 | break :fn_decl switch (callee_val.tag()) { | 4187 | break :fn_decl switch (callee_val.tag()) { |
| 4188 | .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl, | 4188 | .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl, |
| 4189 | .function => callee_val.castTag(.function).?.data.owner_decl, | 4189 | .function => callee_val.castTag(.function).?.data.owner_decl, |
| ... | @@ -4269,7 +4269,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4269,7 +4269,7 @@ fn airDbgVar(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4269 | const mod = f.object.dg.module; | 4269 | const mod = f.object.dg.module; |
| 4270 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; | 4270 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; |
| 4271 | const name = f.air.nullTerminatedString(pl_op.payload); | 4271 | const name = f.air.nullTerminatedString(pl_op.payload); |
| 4272 | const operand_is_undef = if (f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep() else false; | 4272 | const operand_is_undef = if (try f.air.value(pl_op.operand, mod)) |v| v.isUndefDeep() else false; |
| 4273 | if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand); | 4273 | if (!operand_is_undef) _ = try f.resolveInst(pl_op.operand); |
| 4274 | 4274 | ||
| 4275 | try reap(f, inst, &.{pl_op.operand}); | 4275 | try reap(f, inst, &.{pl_op.operand}); |
| ... | @@ -4735,7 +4735,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4735,7 +4735,7 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4735 | try f.renderType(writer, Type.usize); | 4735 | try f.renderType(writer, Type.usize); |
| 4736 | try writer.writeByte(')'); | 4736 | try writer.writeByte(')'); |
| 4737 | } | 4737 | } |
| 4738 | try f.object.dg.renderValue(writer, condition_ty, f.air.value(item, mod).?, .Other); | 4738 | try f.object.dg.renderValue(writer, condition_ty, (try f.air.value(item, mod)).?, .Other); |
| 4739 | try writer.writeByte(':'); | 4739 | try writer.writeByte(':'); |
| 4740 | } | 4740 | } |
| 4741 | try writer.writeByte(' '); | 4741 | try writer.writeByte(' '); |
| ... | @@ -5069,7 +5069,7 @@ fn airIsNull( | ... | @@ -5069,7 +5069,7 @@ fn airIsNull( |
| 5069 | // operand is a regular pointer, test `operand !=/== NULL` | 5069 | // operand is a regular pointer, test `operand !=/== NULL` |
| 5070 | TypedValue{ .ty = optional_ty, .val = Value.null } | 5070 | TypedValue{ .ty = optional_ty, .val = Value.null } |
| 5071 | else if (payload_ty.zigTypeTag(mod) == .ErrorSet) | 5071 | else if (payload_ty.zigTypeTag(mod) == .ErrorSet) |
| 5072 | TypedValue{ .ty = payload_ty, .val = Value.zero } | 5072 | TypedValue{ .ty = payload_ty, .val = try mod.intValue(payload_ty, 0) } |
| 5073 | else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: { | 5073 | else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: { |
| 5074 | try writer.writeAll(".ptr"); | 5074 | try writer.writeAll(".ptr"); |
| 5075 | const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod); | 5075 | const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod); |
| ... | @@ -5325,7 +5325,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5325,7 +5325,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5325 | }, | 5325 | }, |
| 5326 | .end => { | 5326 | .end => { |
| 5327 | try f.writeCValue(writer, field_ptr_val, .Other); | 5327 | try f.writeCValue(writer, field_ptr_val, .Other); |
| 5328 | try writer.print(" - {}", .{try f.fmtIntLiteral(Type.usize, Value.one)}); | 5328 | try writer.print(" - {}", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))}); |
| 5329 | }, | 5329 | }, |
| 5330 | } | 5330 | } |
| 5331 | 5331 | ||
| ... | @@ -5378,7 +5378,7 @@ fn fieldPtr( | ... | @@ -5378,7 +5378,7 @@ fn fieldPtr( |
| 5378 | .end => { | 5378 | .end => { |
| 5379 | try writer.writeByte('('); | 5379 | try writer.writeByte('('); |
| 5380 | try f.writeCValue(writer, container_ptr_val, .Other); | 5380 | try f.writeCValue(writer, container_ptr_val, .Other); |
| 5381 | try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, Value.one)}); | 5381 | try writer.print(" + {})", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))}); |
| 5382 | }, | 5382 | }, |
| 5383 | } | 5383 | } |
| 5384 | 5384 | ||
| ... | @@ -5546,7 +5546,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5546,7 +5546,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5546 | else | 5546 | else |
| 5547 | try f.writeCValueMember(writer, operand, .{ .identifier = "error" }) | 5547 | try f.writeCValueMember(writer, operand, .{ .identifier = "error" }) |
| 5548 | else | 5548 | else |
| 5549 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); | 5549 | try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Initializer); |
| 5550 | } | 5550 | } |
| 5551 | try writer.writeAll(";\n"); | 5551 | try writer.writeAll(";\n"); |
| 5552 | return local; | 5552 | return local; |
| ... | @@ -5673,7 +5673,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5673,7 +5673,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5673 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5673 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5674 | try f.writeCValueDeref(writer, operand); | 5674 | try f.writeCValueDeref(writer, operand); |
| 5675 | try writer.writeAll(" = "); | 5675 | try writer.writeAll(" = "); |
| 5676 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); | 5676 | try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other); |
| 5677 | try writer.writeAll(";\n "); | 5677 | try writer.writeAll(";\n "); |
| 5678 | 5678 | ||
| 5679 | return operand; | 5679 | return operand; |
| ... | @@ -5681,7 +5681,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5681,7 +5681,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5681 | try reap(f, inst, &.{ty_op.operand}); | 5681 | try reap(f, inst, &.{ty_op.operand}); |
| 5682 | try f.writeCValueDeref(writer, operand); | 5682 | try f.writeCValueDeref(writer, operand); |
| 5683 | try writer.writeAll(".error = "); | 5683 | try writer.writeAll(".error = "); |
| 5684 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); | 5684 | try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other); |
| 5685 | try writer.writeAll(";\n"); | 5685 | try writer.writeAll(";\n"); |
| 5686 | 5686 | ||
| 5687 | // Then return the payload pointer (only if it is used) | 5687 | // Then return the payload pointer (only if it is used) |
| ... | @@ -5737,7 +5737,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5737,7 +5737,7 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5737 | else | 5737 | else |
| 5738 | try f.writeCValueMember(writer, local, .{ .identifier = "error" }); | 5738 | try f.writeCValueMember(writer, local, .{ .identifier = "error" }); |
| 5739 | try a.assign(f, writer); | 5739 | try a.assign(f, writer); |
| 5740 | try f.object.dg.renderValue(writer, err_ty, Value.zero, .Other); | 5740 | try f.object.dg.renderValue(writer, err_ty, try mod.intValue(err_ty, 0), .Other); |
| 5741 | try a.end(f, writer); | 5741 | try a.end(f, writer); |
| 5742 | } | 5742 | } |
| 5743 | return local; | 5743 | return local; |
| ... | @@ -5768,11 +5768,11 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const | ... | @@ -5768,11 +5768,11 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const |
| 5768 | else | 5768 | else |
| 5769 | try f.writeCValue(writer, operand, .Other) | 5769 | try f.writeCValue(writer, operand, .Other) |
| 5770 | else | 5770 | else |
| 5771 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); | 5771 | try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other); |
| 5772 | try writer.writeByte(' '); | 5772 | try writer.writeByte(' '); |
| 5773 | try writer.writeAll(operator); | 5773 | try writer.writeAll(operator); |
| 5774 | try writer.writeByte(' '); | 5774 | try writer.writeByte(' '); |
| 5775 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); | 5775 | try f.object.dg.renderValue(writer, error_ty, try mod.intValue(error_ty, 0), .Other); |
| 5776 | try writer.writeAll(";\n"); | 5776 | try writer.writeAll(";\n"); |
| 5777 | return local; | 5777 | return local; |
| 5778 | } | 5778 | } |
| ... | @@ -5798,7 +5798,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -5798,7 +5798,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 5798 | } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 5798 | } else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 5799 | try writer.writeAll("&("); | 5799 | try writer.writeAll("&("); |
| 5800 | try f.writeCValueDeref(writer, operand); | 5800 | try f.writeCValueDeref(writer, operand); |
| 5801 | try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, Value.zero)}); | 5801 | try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 0))}); |
| 5802 | } else try f.writeCValue(writer, operand, .Initializer); | 5802 | } else try f.writeCValue(writer, operand, .Initializer); |
| 5803 | try writer.writeAll("; "); | 5803 | try writer.writeAll("; "); |
| 5804 | 5804 | ||
| ... | @@ -6022,7 +6022,7 @@ fn airCmpBuiltinCall( | ... | @@ -6022,7 +6022,7 @@ fn airCmpBuiltinCall( |
| 6022 | try writer.writeByte(')'); | 6022 | try writer.writeByte(')'); |
| 6023 | if (!ref_ret) try writer.print(" {s} {}", .{ | 6023 | if (!ref_ret) try writer.print(" {s} {}", .{ |
| 6024 | compareOperatorC(operator), | 6024 | compareOperatorC(operator), |
| 6025 | try f.fmtIntLiteral(Type.i32, Value.zero), | 6025 | try f.fmtIntLiteral(Type.i32, try mod.intValue(Type.i32, 0)), |
| 6026 | }); | 6026 | }); |
| 6027 | try writer.writeAll(";\n"); | 6027 | try writer.writeAll(";\n"); |
| 6028 | try v.end(f, inst, writer); | 6028 | try v.end(f, inst, writer); |
| ... | @@ -6278,7 +6278,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -6278,7 +6278,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6278 | const value = try f.resolveInst(bin_op.rhs); | 6278 | const value = try f.resolveInst(bin_op.rhs); |
| 6279 | const elem_ty = f.typeOf(bin_op.rhs); | 6279 | const elem_ty = f.typeOf(bin_op.rhs); |
| 6280 | const elem_abi_size = elem_ty.abiSize(mod); | 6280 | const elem_abi_size = elem_ty.abiSize(mod); |
| 6281 | const val_is_undef = if (f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false; | 6281 | const val_is_undef = if (try f.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false; |
| 6282 | const writer = f.object.writer(); | 6282 | const writer = f.object.writer(); |
| 6283 | 6283 | ||
| 6284 | if (val_is_undef) { | 6284 | if (val_is_undef) { |
| ... | @@ -6326,7 +6326,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { | ... | @@ -6326,7 +6326,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6326 | try writer.writeAll("for ("); | 6326 | try writer.writeAll("for ("); |
| 6327 | try f.writeCValue(writer, index, .Other); | 6327 | try f.writeCValue(writer, index, .Other); |
| 6328 | try writer.writeAll(" = "); | 6328 | try writer.writeAll(" = "); |
| 6329 | try f.object.dg.renderValue(writer, Type.usize, Value.zero, .Initializer); | 6329 | try f.object.dg.renderValue(writer, Type.usize, try mod.intValue(Type.usize, 0), .Initializer); |
| 6330 | try writer.writeAll("; "); | 6330 | try writer.writeAll("; "); |
| 6331 | try f.writeCValue(writer, index, .Other); | 6331 | try f.writeCValue(writer, index, .Other); |
| 6332 | try writer.writeAll(" != "); | 6332 | try writer.writeAll(" != "); |
| ... | @@ -6677,27 +6677,27 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -6677,27 +6677,27 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6677 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); | 6677 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); |
| 6678 | 6678 | ||
| 6679 | try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) { | 6679 | try f.object.dg.renderValue(writer, scalar_ty, switch (reduce.operation) { |
| 6680 | .Or, .Xor, .Add => Value.zero, | 6680 | .Or, .Xor, .Add => try mod.intValue(scalar_ty, 0), |
| 6681 | .And => switch (scalar_ty.zigTypeTag(mod)) { | 6681 | .And => switch (scalar_ty.zigTypeTag(mod)) { |
| 6682 | .Bool => Value.one, | 6682 | .Bool => try mod.intValue(Type.comptime_int, 1), |
| 6683 | else => switch (scalar_ty.intInfo(mod).signedness) { | 6683 | else => switch (scalar_ty.intInfo(mod).signedness) { |
| 6684 | .unsigned => try scalar_ty.maxIntScalar(mod), | 6684 | .unsigned => try scalar_ty.maxIntScalar(mod), |
| 6685 | .signed => Value.negative_one, | 6685 | .signed => try mod.intValue(scalar_ty, -1), |
| 6686 | }, | 6686 | }, |
| 6687 | }, | 6687 | }, |
| 6688 | .Min => switch (scalar_ty.zigTypeTag(mod)) { | 6688 | .Min => switch (scalar_ty.zigTypeTag(mod)) { |
| 6689 | .Bool => Value.one, | 6689 | .Bool => try mod.intValue(Type.comptime_int, 1), |
| 6690 | .Int => try scalar_ty.maxIntScalar(mod), | 6690 | .Int => try scalar_ty.maxIntScalar(mod), |
| 6691 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), | 6691 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), |
| 6692 | else => unreachable, | 6692 | else => unreachable, |
| 6693 | }, | 6693 | }, |
| 6694 | .Max => switch (scalar_ty.zigTypeTag(mod)) { | 6694 | .Max => switch (scalar_ty.zigTypeTag(mod)) { |
| 6695 | .Bool => Value.zero, | 6695 | .Bool => try mod.intValue(scalar_ty, 0), |
| 6696 | .Int => try scalar_ty.minInt(stack.get(), mod), | 6696 | .Int => try scalar_ty.minInt(stack.get(), mod), |
| 6697 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), | 6697 | .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target), |
| 6698 | else => unreachable, | 6698 | else => unreachable, |
| 6699 | }, | 6699 | }, |
| 6700 | .Mul => Value.one, | 6700 | .Mul => try mod.intValue(Type.comptime_int, 1), |
| 6701 | }, .Initializer); | 6701 | }, .Initializer); |
| 6702 | try writer.writeAll(";\n"); | 6702 | try writer.writeAll(";\n"); |
| 6703 | 6703 | ||
| ... | @@ -7686,13 +7686,13 @@ const Vectorize = struct { | ... | @@ -7686,13 +7686,13 @@ const Vectorize = struct { |
| 7686 | 7686 | ||
| 7687 | try writer.writeAll("for ("); | 7687 | try writer.writeAll("for ("); |
| 7688 | try f.writeCValue(writer, local, .Other); | 7688 | try f.writeCValue(writer, local, .Other); |
| 7689 | try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, Value.zero)}); | 7689 | try writer.print(" = {d}; ", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 0))}); |
| 7690 | try f.writeCValue(writer, local, .Other); | 7690 | try f.writeCValue(writer, local, .Other); |
| 7691 | try writer.print(" < {d}; ", .{ | 7691 | try writer.print(" < {d}; ", .{ |
| 7692 | try f.fmtIntLiteral(Type.usize, len_val), | 7692 | try f.fmtIntLiteral(Type.usize, len_val), |
| 7693 | }); | 7693 | }); |
| 7694 | try f.writeCValue(writer, local, .Other); | 7694 | try f.writeCValue(writer, local, .Other); |
| 7695 | try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, Value.one)}); | 7695 | try writer.print(" += {d}) {{\n", .{try f.fmtIntLiteral(Type.usize, try mod.intValue(Type.usize, 1))}); |
| 7696 | f.object.indent_writer.pushIndent(); | 7696 | f.object.indent_writer.pushIndent(); |
| 7697 | 7697 | ||
| 7698 | break :index .{ .index = local }; | 7698 | break :index .{ .index = local }; |
src/codegen/llvm.zig+9-9| ... | @@ -2854,7 +2854,7 @@ pub const DeclGen = struct { | ... | @@ -2854,7 +2854,7 @@ pub const DeclGen = struct { |
| 2854 | }, | 2854 | }, |
| 2855 | .Array => { | 2855 | .Array => { |
| 2856 | const elem_ty = t.childType(mod); | 2856 | const elem_ty = t.childType(mod); |
| 2857 | assert(elem_ty.onePossibleValue(mod) == null); | 2857 | if (std.debug.runtime_safety) assert((try elem_ty.onePossibleValue(mod)) == null); |
| 2858 | const elem_llvm_ty = try dg.lowerType(elem_ty); | 2858 | const elem_llvm_ty = try dg.lowerType(elem_ty); |
| 2859 | const total_len = t.arrayLen(mod) + @boolToInt(t.sentinel(mod) != null); | 2859 | const total_len = t.arrayLen(mod) + @boolToInt(t.sentinel(mod) != null); |
| 2860 | return elem_llvm_ty.arrayType(@intCast(c_uint, total_len)); | 2860 | return elem_llvm_ty.arrayType(@intCast(c_uint, total_len)); |
| ... | @@ -3588,7 +3588,7 @@ pub const DeclGen = struct { | ... | @@ -3588,7 +3588,7 @@ pub const DeclGen = struct { |
| 3588 | 3588 | ||
| 3589 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { | 3589 | if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) { |
| 3590 | // We use the error type directly as the type. | 3590 | // We use the error type directly as the type. |
| 3591 | const err_val = if (!is_pl) tv.val else Value.zero; | 3591 | const err_val = if (!is_pl) tv.val else try mod.intValue(Type.anyerror, 0); |
| 3592 | return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val }); | 3592 | return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val }); |
| 3593 | } | 3593 | } |
| 3594 | 3594 | ||
| ... | @@ -3596,7 +3596,7 @@ pub const DeclGen = struct { | ... | @@ -3596,7 +3596,7 @@ pub const DeclGen = struct { |
| 3596 | const error_align = Type.anyerror.abiAlignment(mod); | 3596 | const error_align = Type.anyerror.abiAlignment(mod); |
| 3597 | const llvm_error_value = try dg.lowerValue(.{ | 3597 | const llvm_error_value = try dg.lowerValue(.{ |
| 3598 | .ty = Type.anyerror, | 3598 | .ty = Type.anyerror, |
| 3599 | .val = if (is_pl) Value.zero else tv.val, | 3599 | .val = if (is_pl) try mod.intValue(Type.anyerror, 0) else tv.val, |
| 3600 | }); | 3600 | }); |
| 3601 | const llvm_payload_value = try dg.lowerValue(.{ | 3601 | const llvm_payload_value = try dg.lowerValue(.{ |
| 3602 | .ty = payload_type, | 3602 | .ty = payload_type, |
| ... | @@ -4476,7 +4476,7 @@ pub const FuncGen = struct { | ... | @@ -4476,7 +4476,7 @@ pub const FuncGen = struct { |
| 4476 | const mod = self.dg.module; | 4476 | const mod = self.dg.module; |
| 4477 | const llvm_val = try self.resolveValue(.{ | 4477 | const llvm_val = try self.resolveValue(.{ |
| 4478 | .ty = self.typeOf(inst), | 4478 | .ty = self.typeOf(inst), |
| 4479 | .val = self.air.value(inst, mod).?, | 4479 | .val = (try self.air.value(inst, mod)).?, |
| 4480 | }); | 4480 | }); |
| 4481 | gop.value_ptr.* = llvm_val; | 4481 | gop.value_ptr.* = llvm_val; |
| 4482 | return llvm_val; | 4482 | return llvm_val; |
| ... | @@ -6873,7 +6873,7 @@ pub const FuncGen = struct { | ... | @@ -6873,7 +6873,7 @@ pub const FuncGen = struct { |
| 6873 | const err_union_ty = self.typeOf(ty_op.operand).childType(mod); | 6873 | const err_union_ty = self.typeOf(ty_op.operand).childType(mod); |
| 6874 | 6874 | ||
| 6875 | const payload_ty = err_union_ty.errorUnionPayload(); | 6875 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 6876 | const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero }); | 6876 | const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.anyerror, 0) }); |
| 6877 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { | 6877 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { |
| 6878 | _ = self.builder.buildStore(non_error_val, operand); | 6878 | _ = self.builder.buildStore(non_error_val, operand); |
| 6879 | return operand; | 6879 | return operand; |
| ... | @@ -8203,7 +8203,7 @@ pub const FuncGen = struct { | ... | @@ -8203,7 +8203,7 @@ pub const FuncGen = struct { |
| 8203 | const ptr_ty = self.typeOf(bin_op.lhs); | 8203 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 8204 | const operand_ty = ptr_ty.childType(mod); | 8204 | const operand_ty = ptr_ty.childType(mod); |
| 8205 | 8205 | ||
| 8206 | const val_is_undef = if (self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false; | 8206 | const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false; |
| 8207 | if (val_is_undef) { | 8207 | if (val_is_undef) { |
| 8208 | // Even if safety is disabled, we still emit a memset to undefined since it conveys | 8208 | // Even if safety is disabled, we still emit a memset to undefined since it conveys |
| 8209 | // extra information to LLVM. However, safety makes the difference between using | 8209 | // extra information to LLVM. However, safety makes the difference between using |
| ... | @@ -8494,7 +8494,7 @@ pub const FuncGen = struct { | ... | @@ -8494,7 +8494,7 @@ pub const FuncGen = struct { |
| 8494 | const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty); | 8494 | const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty); |
| 8495 | const is_volatile = ptr_ty.isVolatilePtr(mod); | 8495 | const is_volatile = ptr_ty.isVolatilePtr(mod); |
| 8496 | 8496 | ||
| 8497 | if (self.air.value(bin_op.rhs, mod)) |elem_val| { | 8497 | if (try self.air.value(bin_op.rhs, mod)) |elem_val| { |
| 8498 | if (elem_val.isUndefDeep()) { | 8498 | if (elem_val.isUndefDeep()) { |
| 8499 | // Even if safety is disabled, we still emit a memset to undefined since it conveys | 8499 | // Even if safety is disabled, we still emit a memset to undefined since it conveys |
| 8500 | // extra information to LLVM. However, safety makes the difference between using | 8500 | // extra information to LLVM. However, safety makes the difference between using |
| ... | @@ -9323,7 +9323,7 @@ pub const FuncGen = struct { | ... | @@ -9323,7 +9323,7 @@ pub const FuncGen = struct { |
| 9323 | 9323 | ||
| 9324 | var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined }; | 9324 | var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined }; |
| 9325 | for (elements, 0..) |elem, i| { | 9325 | for (elements, 0..) |elem, i| { |
| 9326 | if (result_ty.structFieldValueComptime(mod, i) != null) continue; | 9326 | if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue; |
| 9327 | 9327 | ||
| 9328 | const llvm_elem = try self.resolveInst(elem); | 9328 | const llvm_elem = try self.resolveInst(elem); |
| 9329 | const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?; | 9329 | const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?; |
| ... | @@ -9344,7 +9344,7 @@ pub const FuncGen = struct { | ... | @@ -9344,7 +9344,7 @@ pub const FuncGen = struct { |
| 9344 | } else { | 9344 | } else { |
| 9345 | var result = llvm_result_ty.getUndef(); | 9345 | var result = llvm_result_ty.getUndef(); |
| 9346 | for (elements, 0..) |elem, i| { | 9346 | for (elements, 0..) |elem, i| { |
| 9347 | if (result_ty.structFieldValueComptime(mod, i) != null) continue; | 9347 | if ((try result_ty.structFieldValueComptime(mod, i)) != null) continue; |
| 9348 | 9348 | ||
| 9349 | const llvm_elem = try self.resolveInst(elem); | 9349 | const llvm_elem = try self.resolveInst(elem); |
| 9350 | const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?; | 9350 | const llvm_i = llvmFieldIndex(result_ty, i, mod, &ptr_ty_buf).?; |
src/codegen/spirv.zig+5-5| ... | @@ -232,7 +232,7 @@ pub const DeclGen = struct { | ... | @@ -232,7 +232,7 @@ pub const DeclGen = struct { |
| 232 | /// Fetch the result-id for a previously generated instruction or constant. | 232 | /// Fetch the result-id for a previously generated instruction or constant. |
| 233 | fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef { | 233 | fn resolve(self: *DeclGen, inst: Air.Inst.Ref) !IdRef { |
| 234 | const mod = self.module; | 234 | const mod = self.module; |
| 235 | if (self.air.value(inst, mod)) |val| { | 235 | if (try self.air.value(inst, mod)) |val| { |
| 236 | const ty = self.typeOf(inst); | 236 | const ty = self.typeOf(inst); |
| 237 | if (ty.zigTypeTag(mod) == .Fn) { | 237 | if (ty.zigTypeTag(mod) == .Fn) { |
| 238 | const fn_decl_index = switch (val.tag()) { | 238 | const fn_decl_index = switch (val.tag()) { |
| ... | @@ -584,7 +584,7 @@ pub const DeclGen = struct { | ... | @@ -584,7 +584,7 @@ pub const DeclGen = struct { |
| 584 | // TODO: Properly lower function pointers. For now we are going to hack around it and | 584 | // TODO: Properly lower function pointers. For now we are going to hack around it and |
| 585 | // just generate an empty pointer. Function pointers are represented by usize for now, | 585 | // just generate an empty pointer. Function pointers are represented by usize for now, |
| 586 | // though. | 586 | // though. |
| 587 | try self.addInt(Type.usize, Value.zero); | 587 | try self.addInt(Type.usize, Value.zero_usize); |
| 588 | // TODO: Add dependency | 588 | // TODO: Add dependency |
| 589 | return; | 589 | return; |
| 590 | }, | 590 | }, |
| ... | @@ -803,7 +803,7 @@ pub const DeclGen = struct { | ... | @@ -803,7 +803,7 @@ pub const DeclGen = struct { |
| 803 | .ErrorUnion => { | 803 | .ErrorUnion => { |
| 804 | const payload_ty = ty.errorUnionPayload(); | 804 | const payload_ty = ty.errorUnionPayload(); |
| 805 | const is_pl = val.errorUnionIsPayload(); | 805 | const is_pl = val.errorUnionIsPayload(); |
| 806 | const error_val = if (!is_pl) val else Value.zero; | 806 | const error_val = if (!is_pl) val else try mod.intValue(Type.anyerror, 0); |
| 807 | 807 | ||
| 808 | const eu_layout = dg.errorUnionLayout(payload_ty); | 808 | const eu_layout = dg.errorUnionLayout(payload_ty); |
| 809 | if (!eu_layout.payload_has_bits) { | 809 | if (!eu_layout.payload_has_bits) { |
| ... | @@ -2801,7 +2801,7 @@ pub const DeclGen = struct { | ... | @@ -2801,7 +2801,7 @@ pub const DeclGen = struct { |
| 2801 | const value = try self.resolve(bin_op.rhs); | 2801 | const value = try self.resolve(bin_op.rhs); |
| 2802 | const ptr_ty_ref = try self.resolveType(ptr_ty, .direct); | 2802 | const ptr_ty_ref = try self.resolveType(ptr_ty, .direct); |
| 2803 | 2803 | ||
| 2804 | const val_is_undef = if (self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false; | 2804 | const val_is_undef = if (try self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false; |
| 2805 | if (val_is_undef) { | 2805 | if (val_is_undef) { |
| 2806 | const undef = try self.spv.constUndef(ptr_ty_ref); | 2806 | const undef = try self.spv.constUndef(ptr_ty_ref); |
| 2807 | try self.store(ptr_ty, ptr, undef); | 2807 | try self.store(ptr_ty, ptr, undef); |
| ... | @@ -3141,7 +3141,7 @@ pub const DeclGen = struct { | ... | @@ -3141,7 +3141,7 @@ pub const DeclGen = struct { |
| 3141 | const label = IdRef{ .id = first_case_label.id + case_i }; | 3141 | const label = IdRef{ .id = first_case_label.id + case_i }; |
| 3142 | 3142 | ||
| 3143 | for (items) |item| { | 3143 | for (items) |item| { |
| 3144 | const value = self.air.value(item, mod) orelse { | 3144 | const value = (try self.air.value(item, mod)) orelse { |
| 3145 | return self.todo("switch on runtime value???", .{}); | 3145 | return self.todo("switch on runtime value???", .{}); |
| 3146 | }; | 3146 | }; |
| 3147 | const int_val = switch (cond_ty.zigTypeTag(mod)) { | 3147 | const int_val = switch (cond_ty.zigTypeTag(mod)) { |
src/type.zig+22-22| ... | @@ -3377,7 +3377,7 @@ pub const Type = struct { | ... | @@ -3377,7 +3377,7 @@ pub const Type = struct { |
| 3377 | } | 3377 | } |
| 3378 | 3378 | ||
| 3379 | /// For vectors, returns the element type. Otherwise returns self. | 3379 | /// For vectors, returns the element type. Otherwise returns self. |
| 3380 | pub fn scalarType(ty: Type, mod: *const Module) Type { | 3380 | pub fn scalarType(ty: Type, mod: *Module) Type { |
| 3381 | return switch (ty.zigTypeTag(mod)) { | 3381 | return switch (ty.zigTypeTag(mod)) { |
| 3382 | .Vector => ty.childType(mod), | 3382 | .Vector => ty.childType(mod), |
| 3383 | else => ty, | 3383 | else => ty, |
| ... | @@ -3941,13 +3941,13 @@ pub const Type = struct { | ... | @@ -3941,13 +3941,13 @@ pub const Type = struct { |
| 3941 | 3941 | ||
| 3942 | /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which | 3942 | /// During semantic analysis, instead call `Sema.typeHasOnePossibleValue` which |
| 3943 | /// resolves field types rather than asserting they are already resolved. | 3943 | /// resolves field types rather than asserting they are already resolved. |
| 3944 | pub fn onePossibleValue(starting_type: Type, mod: *const Module) ?Value { | 3944 | pub fn onePossibleValue(starting_type: Type, mod: *Module) !?Value { |
| 3945 | var ty = starting_type; | 3945 | var ty = starting_type; |
| 3946 | 3946 | ||
| 3947 | if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { | 3947 | if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { |
| 3948 | .int_type => |int_type| { | 3948 | .int_type => |int_type| { |
| 3949 | if (int_type.bits == 0) { | 3949 | if (int_type.bits == 0) { |
| 3950 | return Value.zero; | 3950 | return try mod.intValue(ty, 0); |
| 3951 | } else { | 3951 | } else { |
| 3952 | return null; | 3952 | return null; |
| 3953 | } | 3953 | } |
| ... | @@ -3956,13 +3956,13 @@ pub const Type = struct { | ... | @@ -3956,13 +3956,13 @@ pub const Type = struct { |
| 3956 | .array_type => |array_type| { | 3956 | .array_type => |array_type| { |
| 3957 | if (array_type.len == 0) | 3957 | if (array_type.len == 0) |
| 3958 | return Value.initTag(.empty_array); | 3958 | return Value.initTag(.empty_array); |
| 3959 | if (array_type.child.toType().onePossibleValue(mod) != null) | 3959 | if ((try array_type.child.toType().onePossibleValue(mod)) != null) |
| 3960 | return Value.initTag(.the_only_possible_value); | 3960 | return Value.initTag(.the_only_possible_value); |
| 3961 | return null; | 3961 | return null; |
| 3962 | }, | 3962 | }, |
| 3963 | .vector_type => |vector_type| { | 3963 | .vector_type => |vector_type| { |
| 3964 | if (vector_type.len == 0) return Value.initTag(.empty_array); | 3964 | if (vector_type.len == 0) return Value.initTag(.empty_array); |
| 3965 | if (vector_type.child.toType().onePossibleValue(mod)) |v| return v; | 3965 | if (try vector_type.child.toType().onePossibleValue(mod)) |v| return v; |
| 3966 | return null; | 3966 | return null; |
| 3967 | }, | 3967 | }, |
| 3968 | .opt_type => |child| { | 3968 | .opt_type => |child| { |
| ... | @@ -4055,7 +4055,7 @@ pub const Type = struct { | ... | @@ -4055,7 +4055,7 @@ pub const Type = struct { |
| 4055 | assert(s.haveFieldTypes()); | 4055 | assert(s.haveFieldTypes()); |
| 4056 | for (s.fields.values()) |field| { | 4056 | for (s.fields.values()) |field| { |
| 4057 | if (field.is_comptime) continue; | 4057 | if (field.is_comptime) continue; |
| 4058 | if (field.ty.onePossibleValue(mod) != null) continue; | 4058 | if ((try field.ty.onePossibleValue(mod)) != null) continue; |
| 4059 | return null; | 4059 | return null; |
| 4060 | } | 4060 | } |
| 4061 | return Value.initTag(.empty_struct_value); | 4061 | return Value.initTag(.empty_struct_value); |
| ... | @@ -4066,7 +4066,7 @@ pub const Type = struct { | ... | @@ -4066,7 +4066,7 @@ pub const Type = struct { |
| 4066 | for (tuple.values, 0..) |val, i| { | 4066 | for (tuple.values, 0..) |val, i| { |
| 4067 | const is_comptime = val.ip_index != .unreachable_value; | 4067 | const is_comptime = val.ip_index != .unreachable_value; |
| 4068 | if (is_comptime) continue; | 4068 | if (is_comptime) continue; |
| 4069 | if (tuple.types[i].onePossibleValue(mod) != null) continue; | 4069 | if ((try tuple.types[i].onePossibleValue(mod)) != null) continue; |
| 4070 | return null; | 4070 | return null; |
| 4071 | } | 4071 | } |
| 4072 | return Value.initTag(.empty_struct_value); | 4072 | return Value.initTag(.empty_struct_value); |
| ... | @@ -4089,7 +4089,7 @@ pub const Type = struct { | ... | @@ -4089,7 +4089,7 @@ pub const Type = struct { |
| 4089 | switch (enum_full.fields.count()) { | 4089 | switch (enum_full.fields.count()) { |
| 4090 | 0 => return Value.@"unreachable", | 4090 | 0 => return Value.@"unreachable", |
| 4091 | 1 => if (enum_full.values.count() == 0) { | 4091 | 1 => if (enum_full.values.count() == 0) { |
| 4092 | return Value.zero; // auto-numbered | 4092 | return try mod.intValue(ty, 0); // auto-numbered |
| 4093 | } else { | 4093 | } else { |
| 4094 | return enum_full.values.keys()[0]; | 4094 | return enum_full.values.keys()[0]; |
| 4095 | }, | 4095 | }, |
| ... | @@ -4100,24 +4100,24 @@ pub const Type = struct { | ... | @@ -4100,24 +4100,24 @@ pub const Type = struct { |
| 4100 | const enum_simple = ty.castTag(.enum_simple).?.data; | 4100 | const enum_simple = ty.castTag(.enum_simple).?.data; |
| 4101 | switch (enum_simple.fields.count()) { | 4101 | switch (enum_simple.fields.count()) { |
| 4102 | 0 => return Value.@"unreachable", | 4102 | 0 => return Value.@"unreachable", |
| 4103 | 1 => return Value.zero, | 4103 | 1 => return try mod.intValue(ty, 0), |
| 4104 | else => return null, | 4104 | else => return null, |
| 4105 | } | 4105 | } |
| 4106 | }, | 4106 | }, |
| 4107 | .enum_nonexhaustive => { | 4107 | .enum_nonexhaustive => { |
| 4108 | const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty; | 4108 | const tag_ty = ty.castTag(.enum_nonexhaustive).?.data.tag_ty; |
| 4109 | if (!tag_ty.hasRuntimeBits(mod)) { | 4109 | if (!tag_ty.hasRuntimeBits(mod)) { |
| 4110 | return Value.zero; | 4110 | return try mod.intValue(ty, 0); |
| 4111 | } else { | 4111 | } else { |
| 4112 | return null; | 4112 | return null; |
| 4113 | } | 4113 | } |
| 4114 | }, | 4114 | }, |
| 4115 | .@"union", .union_safety_tagged, .union_tagged => { | 4115 | .@"union", .union_safety_tagged, .union_tagged => { |
| 4116 | const union_obj = ty.cast(Payload.Union).?.data; | 4116 | const union_obj = ty.cast(Payload.Union).?.data; |
| 4117 | const tag_val = union_obj.tag_ty.onePossibleValue(mod) orelse return null; | 4117 | const tag_val = (try union_obj.tag_ty.onePossibleValue(mod)) orelse return null; |
| 4118 | if (union_obj.fields.count() == 0) return Value.@"unreachable"; | 4118 | if (union_obj.fields.count() == 0) return Value.@"unreachable"; |
| 4119 | const only_field = union_obj.fields.values()[0]; | 4119 | const only_field = union_obj.fields.values()[0]; |
| 4120 | const val_val = only_field.ty.onePossibleValue(mod) orelse return null; | 4120 | const val_val = (try only_field.ty.onePossibleValue(mod)) orelse return null; |
| 4121 | _ = tag_val; | 4121 | _ = tag_val; |
| 4122 | _ = val_val; | 4122 | _ = val_val; |
| 4123 | return Value.initTag(.empty_struct_value); | 4123 | return Value.initTag(.empty_struct_value); |
| ... | @@ -4128,7 +4128,7 @@ pub const Type = struct { | ... | @@ -4128,7 +4128,7 @@ pub const Type = struct { |
| 4128 | .array => { | 4128 | .array => { |
| 4129 | if (ty.arrayLen(mod) == 0) | 4129 | if (ty.arrayLen(mod) == 0) |
| 4130 | return Value.initTag(.empty_array); | 4130 | return Value.initTag(.empty_array); |
| 4131 | if (ty.childType(mod).onePossibleValue(mod) != null) | 4131 | if ((try ty.childType(mod).onePossibleValue(mod)) != null) |
| 4132 | return Value.initTag(.the_only_possible_value); | 4132 | return Value.initTag(.the_only_possible_value); |
| 4133 | return null; | 4133 | return null; |
| 4134 | }, | 4134 | }, |
| ... | @@ -4365,8 +4365,8 @@ pub const Type = struct { | ... | @@ -4365,8 +4365,8 @@ pub const Type = struct { |
| 4365 | /// Asserts that the type is an integer. | 4365 | /// Asserts that the type is an integer. |
| 4366 | pub fn minIntScalar(ty: Type, mod: *Module) !Value { | 4366 | pub fn minIntScalar(ty: Type, mod: *Module) !Value { |
| 4367 | const info = ty.intInfo(mod); | 4367 | const info = ty.intInfo(mod); |
| 4368 | if (info.signedness == .unsigned) return Value.zero; | 4368 | if (info.signedness == .unsigned) return mod.intValue(ty, 0); |
| 4369 | if (info.bits == 0) return Value.negative_one; | 4369 | if (info.bits == 0) return mod.intValue(ty, -1); |
| 4370 | 4370 | ||
| 4371 | if (std.math.cast(u6, info.bits - 1)) |shift| { | 4371 | if (std.math.cast(u6, info.bits - 1)) |shift| { |
| 4372 | const n = @as(i64, std.math.minInt(i64)) >> (63 - shift); | 4372 | const n = @as(i64, std.math.minInt(i64)) >> (63 - shift); |
| ... | @@ -4392,17 +4392,17 @@ pub const Type = struct { | ... | @@ -4392,17 +4392,17 @@ pub const Type = struct { |
| 4392 | } | 4392 | } |
| 4393 | 4393 | ||
| 4394 | /// Asserts that the type is an integer. | 4394 | /// Asserts that the type is an integer. |
| 4395 | pub fn maxIntScalar(self: Type, mod: *Module) !Value { | 4395 | pub fn maxIntScalar(ty: Type, mod: *Module) !Value { |
| 4396 | const info = self.intInfo(mod); | 4396 | const info = ty.intInfo(mod); |
| 4397 | 4397 | ||
| 4398 | switch (info.bits) { | 4398 | switch (info.bits) { |
| 4399 | 0 => return switch (info.signedness) { | 4399 | 0 => return switch (info.signedness) { |
| 4400 | .signed => Value.negative_one, | 4400 | .signed => mod.intValue(ty, -1), |
| 4401 | .unsigned => Value.zero, | 4401 | .unsigned => mod.intValue(ty, 0), |
| 4402 | }, | 4402 | }, |
| 4403 | 1 => return switch (info.signedness) { | 4403 | 1 => return switch (info.signedness) { |
| 4404 | .signed => Value.zero, | 4404 | .signed => mod.intValue(ty, 0), |
| 4405 | .unsigned => Value.one, | 4405 | .unsigned => mod.intValue(ty, 0), |
| 4406 | }, | 4406 | }, |
| 4407 | else => {}, | 4407 | else => {}, |
| 4408 | } | 4408 | } |
| ... | @@ -4662,7 +4662,7 @@ pub const Type = struct { | ... | @@ -4662,7 +4662,7 @@ pub const Type = struct { |
| 4662 | } | 4662 | } |
| 4663 | } | 4663 | } |
| 4664 | 4664 | ||
| 4665 | pub fn structFieldValueComptime(ty: Type, mod: *const Module, index: usize) ?Value { | 4665 | pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value { |
| 4666 | switch (ty.tag()) { | 4666 | switch (ty.tag()) { |
| 4667 | .@"struct" => { | 4667 | .@"struct" => { |
| 4668 | const struct_obj = ty.castTag(.@"struct").?.data; | 4668 | const struct_obj = ty.castTag(.@"struct").?.data; |
src/value.zig+22-21| ... | @@ -1022,7 +1022,7 @@ pub const Value = struct { | ... | @@ -1022,7 +1022,7 @@ pub const Value = struct { |
| 1022 | if (opt_val) |some| { | 1022 | if (opt_val) |some| { |
| 1023 | return some.writeToMemory(child, mod, buffer); | 1023 | return some.writeToMemory(child, mod, buffer); |
| 1024 | } else { | 1024 | } else { |
| 1025 | return writeToMemory(Value.zero, Type.usize, mod, buffer); | 1025 | return writeToMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer); |
| 1026 | } | 1026 | } |
| 1027 | }, | 1027 | }, |
| 1028 | else => return error.Unimplemented, | 1028 | else => return error.Unimplemented, |
| ... | @@ -1124,7 +1124,7 @@ pub const Value = struct { | ... | @@ -1124,7 +1124,7 @@ pub const Value = struct { |
| 1124 | .Packed => { | 1124 | .Packed => { |
| 1125 | const field_index = ty.unionTagFieldIndex(val.unionTag(), mod); | 1125 | const field_index = ty.unionTagFieldIndex(val.unionTag(), mod); |
| 1126 | const field_type = ty.unionFields().values()[field_index.?].ty; | 1126 | const field_type = ty.unionFields().values()[field_index.?].ty; |
| 1127 | const field_val = val.fieldValue(field_type, mod, field_index.?); | 1127 | const field_val = try val.fieldValue(field_type, mod, field_index.?); |
| 1128 | 1128 | ||
| 1129 | return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset); | 1129 | return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset); |
| 1130 | }, | 1130 | }, |
| ... | @@ -1141,7 +1141,7 @@ pub const Value = struct { | ... | @@ -1141,7 +1141,7 @@ pub const Value = struct { |
| 1141 | if (opt_val) |some| { | 1141 | if (opt_val) |some| { |
| 1142 | return some.writeToPackedMemory(child, mod, buffer, bit_offset); | 1142 | return some.writeToPackedMemory(child, mod, buffer, bit_offset); |
| 1143 | } else { | 1143 | } else { |
| 1144 | return writeToPackedMemory(Value.zero, Type.usize, mod, buffer, bit_offset); | 1144 | return writeToPackedMemory(try mod.intValue(Type.usize, 0), Type.usize, mod, buffer, bit_offset); |
| 1145 | } | 1145 | } |
| 1146 | }, | 1146 | }, |
| 1147 | else => @panic("TODO implement writeToPackedMemory for more types"), | 1147 | else => @panic("TODO implement writeToPackedMemory for more types"), |
| ... | @@ -1173,7 +1173,7 @@ pub const Value = struct { | ... | @@ -1173,7 +1173,7 @@ pub const Value = struct { |
| 1173 | const int_info = ty.intInfo(mod); | 1173 | const int_info = ty.intInfo(mod); |
| 1174 | const bits = int_info.bits; | 1174 | const bits = int_info.bits; |
| 1175 | const byte_count = (bits + 7) / 8; | 1175 | const byte_count = (bits + 7) / 8; |
| 1176 | if (bits == 0 or buffer.len == 0) return Value.zero; | 1176 | if (bits == 0 or buffer.len == 0) return mod.intValue(ty, 0); |
| 1177 | 1177 | ||
| 1178 | if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64 | 1178 | if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64 |
| 1179 | .signed => { | 1179 | .signed => { |
| ... | @@ -1290,12 +1290,12 @@ pub const Value = struct { | ... | @@ -1290,12 +1290,12 @@ pub const Value = struct { |
| 1290 | } | 1290 | } |
| 1291 | }, | 1291 | }, |
| 1292 | .Int, .Enum => { | 1292 | .Int, .Enum => { |
| 1293 | if (buffer.len == 0) return Value.zero; | 1293 | if (buffer.len == 0) return mod.intValue(ty, 0); |
| 1294 | const int_info = ty.intInfo(mod); | 1294 | const int_info = ty.intInfo(mod); |
| 1295 | const abi_size = @intCast(usize, ty.abiSize(mod)); | 1295 | const abi_size = @intCast(usize, ty.abiSize(mod)); |
| 1296 | 1296 | ||
| 1297 | const bits = int_info.bits; | 1297 | const bits = int_info.bits; |
| 1298 | if (bits == 0) return Value.zero; | 1298 | if (bits == 0) return mod.intValue(ty, 0); |
| 1299 | if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64 | 1299 | if (bits <= 64) switch (int_info.signedness) { // Fast path for integers <= u64 |
| 1300 | .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)), | 1300 | .signed => return mod.intValue(ty, std.mem.readVarPackedInt(i64, buffer, bit_offset, bits, endian, .signed)), |
| 1301 | .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)), | 1301 | .unsigned => return mod.intValue(ty, std.mem.readVarPackedInt(u64, buffer, bit_offset, bits, endian, .unsigned)), |
| ... | @@ -2091,11 +2091,11 @@ pub const Value = struct { | ... | @@ -2091,11 +2091,11 @@ pub const Value = struct { |
| 2091 | // .the_one_possible_value, | 2091 | // .the_one_possible_value, |
| 2092 | // .aggregate, | 2092 | // .aggregate, |
| 2093 | // Note that we already checked above for matching tags, e.g. both .aggregate. | 2093 | // Note that we already checked above for matching tags, e.g. both .aggregate. |
| 2094 | return ty.onePossibleValue(mod) != null; | 2094 | return (try ty.onePossibleValue(mod)) != null; |
| 2095 | }, | 2095 | }, |
| 2096 | .Union => { | 2096 | .Union => { |
| 2097 | // Here we have to check for value equality, as-if `a` has been coerced to `ty`. | 2097 | // Here we have to check for value equality, as-if `a` has been coerced to `ty`. |
| 2098 | if (ty.onePossibleValue(mod) != null) { | 2098 | if ((try ty.onePossibleValue(mod)) != null) { |
| 2099 | return true; | 2099 | return true; |
| 2100 | } | 2100 | } |
| 2101 | if (a_ty.castTag(.anon_struct)) |payload| { | 2101 | if (a_ty.castTag(.anon_struct)) |payload| { |
| ... | @@ -2604,7 +2604,7 @@ pub const Value = struct { | ... | @@ -2604,7 +2604,7 @@ pub const Value = struct { |
| 2604 | if (data.container_ptr.pointerDecl()) |decl_index| { | 2604 | if (data.container_ptr.pointerDecl()) |decl_index| { |
| 2605 | const container_decl = mod.declPtr(decl_index); | 2605 | const container_decl = mod.declPtr(decl_index); |
| 2606 | const field_type = data.container_ty.structFieldType(data.field_index); | 2606 | const field_type = data.container_ty.structFieldType(data.field_index); |
| 2607 | const field_val = container_decl.val.fieldValue(field_type, mod, data.field_index); | 2607 | const field_val = try container_decl.val.fieldValue(field_type, mod, data.field_index); |
| 2608 | return field_val.elemValue(mod, index); | 2608 | return field_val.elemValue(mod, index); |
| 2609 | } else unreachable; | 2609 | } else unreachable; |
| 2610 | }, | 2610 | }, |
| ... | @@ -2723,7 +2723,7 @@ pub const Value = struct { | ... | @@ -2723,7 +2723,7 @@ pub const Value = struct { |
| 2723 | }; | 2723 | }; |
| 2724 | } | 2724 | } |
| 2725 | 2725 | ||
| 2726 | pub fn fieldValue(val: Value, ty: Type, mod: *const Module, index: usize) Value { | 2726 | pub fn fieldValue(val: Value, ty: Type, mod: *Module, index: usize) !Value { |
| 2727 | switch (val.ip_index) { | 2727 | switch (val.ip_index) { |
| 2728 | .undef => return Value.undef, | 2728 | .undef => return Value.undef, |
| 2729 | .none => switch (val.tag()) { | 2729 | .none => switch (val.tag()) { |
| ... | @@ -2737,14 +2737,14 @@ pub const Value = struct { | ... | @@ -2737,14 +2737,14 @@ pub const Value = struct { |
| 2737 | return payload.val; | 2737 | return payload.val; |
| 2738 | }, | 2738 | }, |
| 2739 | 2739 | ||
| 2740 | .the_only_possible_value => return ty.onePossibleValue(mod).?, | 2740 | .the_only_possible_value => return (try ty.onePossibleValue(mod)).?, |
| 2741 | 2741 | ||
| 2742 | .empty_struct_value => { | 2742 | .empty_struct_value => { |
| 2743 | if (ty.isSimpleTupleOrAnonStruct()) { | 2743 | if (ty.isSimpleTupleOrAnonStruct()) { |
| 2744 | const tuple = ty.tupleFields(); | 2744 | const tuple = ty.tupleFields(); |
| 2745 | return tuple.values[index]; | 2745 | return tuple.values[index]; |
| 2746 | } | 2746 | } |
| 2747 | if (ty.structFieldValueComptime(mod, index)) |some| { | 2747 | if (try ty.structFieldValueComptime(mod, index)) |some| { |
| 2748 | return some; | 2748 | return some; |
| 2749 | } | 2749 | } |
| 2750 | unreachable; | 2750 | unreachable; |
| ... | @@ -2968,7 +2968,7 @@ pub const Value = struct { | ... | @@ -2968,7 +2968,7 @@ pub const Value = struct { |
| 2968 | switch (val.ip_index) { | 2968 | switch (val.ip_index) { |
| 2969 | .undef => return val, | 2969 | .undef => return val, |
| 2970 | .none => switch (val.tag()) { | 2970 | .none => switch (val.tag()) { |
| 2971 | .the_only_possible_value => return Value.zero, // for i0, u0 | 2971 | .the_only_possible_value => return Value.float_zero, // for i0, u0 |
| 2972 | .lazy_align => { | 2972 | .lazy_align => { |
| 2973 | const ty = val.castTag(.lazy_align).?.data; | 2973 | const ty = val.castTag(.lazy_align).?.data; |
| 2974 | if (opt_sema) |sema| { | 2974 | if (opt_sema) |sema| { |
| ... | @@ -3402,7 +3402,7 @@ pub const Value = struct { | ... | @@ -3402,7 +3402,7 @@ pub const Value = struct { |
| 3402 | if (lhs.isUndef() or rhs.isUndef()) return Value.undef; | 3402 | if (lhs.isUndef() or rhs.isUndef()) return Value.undef; |
| 3403 | 3403 | ||
| 3404 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod); | 3404 | const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod); |
| 3405 | const all_ones = if (ty.isSignedInt(mod)) Value.negative_one else try ty.maxIntScalar(mod); | 3405 | const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod); |
| 3406 | return bitwiseXor(anded, all_ones, ty, arena, mod); | 3406 | return bitwiseXor(anded, all_ones, ty, arena, mod); |
| 3407 | } | 3407 | } |
| 3408 | 3408 | ||
| ... | @@ -3803,7 +3803,7 @@ pub const Value = struct { | ... | @@ -3803,7 +3803,7 @@ pub const Value = struct { |
| 3803 | bits: u16, | 3803 | bits: u16, |
| 3804 | mod: *Module, | 3804 | mod: *Module, |
| 3805 | ) !Value { | 3805 | ) !Value { |
| 3806 | if (bits == 0) return Value.zero; | 3806 | if (bits == 0) return mod.intValue(ty, 0); |
| 3807 | 3807 | ||
| 3808 | var val_space: Value.BigIntSpace = undefined; | 3808 | var val_space: Value.BigIntSpace = undefined; |
| 3809 | const val_bigint = val.toBigInt(&val_space, mod); | 3809 | const val_bigint = val.toBigInt(&val_space, mod); |
| ... | @@ -4011,9 +4011,9 @@ pub const Value = struct { | ... | @@ -4011,9 +4011,9 @@ pub const Value = struct { |
| 4011 | // The shift is enough to remove all the bits from the number, which means the | 4011 | // The shift is enough to remove all the bits from the number, which means the |
| 4012 | // result is 0 or -1 depending on the sign. | 4012 | // result is 0 or -1 depending on the sign. |
| 4013 | if (lhs_bigint.positive) { | 4013 | if (lhs_bigint.positive) { |
| 4014 | return Value.zero; | 4014 | return mod.intValue(ty, 0); |
| 4015 | } else { | 4015 | } else { |
| 4016 | return Value.negative_one; | 4016 | return mod.intValue(ty, -1); |
| 4017 | } | 4017 | } |
| 4018 | } | 4018 | } |
| 4019 | 4019 | ||
| ... | @@ -5151,10 +5151,9 @@ pub const Value = struct { | ... | @@ -5151,10 +5151,9 @@ pub const Value = struct { |
| 5151 | 5151 | ||
| 5152 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; | 5152 | pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace; |
| 5153 | 5153 | ||
| 5154 | pub const zero: Value = .{ .ip_index = .zero, .legacy = undefined }; | 5154 | pub const zero_usize: Value = .{ .ip_index = .zero_usize, .legacy = undefined }; |
| 5155 | pub const one: Value = .{ .ip_index = .one, .legacy = undefined }; | ||
| 5156 | pub const negative_one: Value = .{ .ip_index = .negative_one, .legacy = undefined }; | ||
| 5157 | pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined }; | 5155 | pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined }; |
| 5156 | pub const float_zero: Value = .{ .ip_index = .zero, .legacy = undefined }; // TODO: replace this! | ||
| 5158 | pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined }; | 5157 | pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined }; |
| 5159 | pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined }; | 5158 | pub const @"null": Value = .{ .ip_index = .null_value, .legacy = undefined }; |
| 5160 | pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined }; | 5159 | pub const @"false": Value = .{ .ip_index = .bool_false, .legacy = undefined }; |
| ... | @@ -5169,7 +5168,9 @@ pub const Value = struct { | ... | @@ -5169,7 +5168,9 @@ pub const Value = struct { |
| 5169 | } | 5168 | } |
| 5170 | 5169 | ||
| 5171 | pub fn boolToInt(x: bool) Value { | 5170 | pub fn boolToInt(x: bool) Value { |
| 5172 | return if (x) Value.one else Value.zero; | 5171 | const zero: Value = .{ .ip_index = .zero, .legacy = undefined }; |
| 5172 | const one: Value = .{ .ip_index = .one, .legacy = undefined }; | ||
| 5173 | return if (x) one else zero; | ||
| 5173 | } | 5174 | } |
| 5174 | 5175 | ||
| 5175 | pub const RuntimeIndex = enum(u32) { | 5176 | pub const RuntimeIndex = enum(u32) { |