authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-26 18:56:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:55-07:00
log1dc01f11401b6ec0be1e7685cdc445d1b10d4f19
treea64c1aa2d0f7f136325971e01ac1ec4ddd79ef13
parent9cd0ca9f482ef7f76d3f3ca683913e9aceaa47fe

InternPool: fix build-exe and compiler-rt crashes


7 files changed, 191 insertions(+), 92 deletions(-)

src/InternPool.zig+83-1
......@@ -2817,6 +2817,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
28172817 },
28182818 .ptr_type => |ptr_type| {
28192819 assert(ptr_type.elem_type != .none);
2820 assert(ptr_type.sentinel == .none or ip.typeOf(ptr_type.sentinel) == ptr_type.elem_type);
28202821
28212822 if (ptr_type.size == .Slice) {
28222823 _ = ip.map.pop();
......@@ -4780,7 +4781,88 @@ pub fn stringToSliceUnwrap(ip: InternPool, s: OptionalNullTerminatedString) ?[:0
47804781}
47814782
47824783pub fn typeOf(ip: InternPool, index: Index) Index {
4783 return ip.indexToKey(index).typeOf();
4784 // This optimization of static keys is required so that typeOf can be called
4785 // on static keys that haven't been added yet during static key initialization.
4786 // An alternative would be to topological sort the static keys, but this would
4787 // mean that the range of type indices would not be dense.
4788 return switch (index) {
4789 .u1_type,
4790 .u8_type,
4791 .i8_type,
4792 .u16_type,
4793 .i16_type,
4794 .u29_type,
4795 .u32_type,
4796 .i32_type,
4797 .u64_type,
4798 .i64_type,
4799 .u80_type,
4800 .u128_type,
4801 .i128_type,
4802 .usize_type,
4803 .isize_type,
4804 .c_char_type,
4805 .c_short_type,
4806 .c_ushort_type,
4807 .c_int_type,
4808 .c_uint_type,
4809 .c_long_type,
4810 .c_ulong_type,
4811 .c_longlong_type,
4812 .c_ulonglong_type,
4813 .c_longdouble_type,
4814 .f16_type,
4815 .f32_type,
4816 .f64_type,
4817 .f80_type,
4818 .f128_type,
4819 .anyopaque_type,
4820 .bool_type,
4821 .void_type,
4822 .type_type,
4823 .anyerror_type,
4824 .comptime_int_type,
4825 .comptime_float_type,
4826 .noreturn_type,
4827 .anyframe_type,
4828 .null_type,
4829 .undefined_type,
4830 .enum_literal_type,
4831 .atomic_order_type,
4832 .atomic_rmw_op_type,
4833 .calling_convention_type,
4834 .address_space_type,
4835 .float_mode_type,
4836 .reduce_op_type,
4837 .call_modifier_type,
4838 .prefetch_options_type,
4839 .export_options_type,
4840 .extern_options_type,
4841 .type_info_type,
4842 .manyptr_u8_type,
4843 .manyptr_const_u8_type,
4844 .manyptr_const_u8_sentinel_0_type,
4845 .single_const_pointer_to_comptime_int_type,
4846 .slice_const_u8_type,
4847 .slice_const_u8_sentinel_0_type,
4848 .anyerror_void_error_union_type,
4849 .generic_poison_type,
4850 .empty_struct_type,
4851 => .type_type,
4852 .undef => .undefined_type,
4853 .zero, .one, .negative_one => .comptime_int_type,
4854 .zero_usize, .one_usize => .usize_type,
4855 .zero_u8, .one_u8, .four_u8 => .u8_type,
4856 .calling_convention_c, .calling_convention_inline => .calling_convention_type,
4857 .void_value => .void_type,
4858 .unreachable_value => .noreturn_type,
4859 .null_value => .null_type,
4860 .bool_true, .bool_false => .bool_type,
4861 .empty_struct => .empty_struct_type,
4862 .generic_poison => .generic_poison_type,
4863 .var_args_param_type, .none => unreachable,
4864 _ => ip.indexToKey(index).typeOf(),
4865 };
47844866}
47854867
47864868/// Assumes that the enum's field indexes equal its value tags.
src/Module.zig-4
......@@ -6898,10 +6898,6 @@ pub fn enumValueFieldIndex(mod: *Module, ty: Type, field_index: u32) Allocator.E
68986898}
68996899
69006900pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
6901 if (std.debug.runtime_safety) {
6902 const tag = ty.zigTypeTag(mod);
6903 assert(tag == .Int or tag == .ComptimeInt);
6904 }
69056901 if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);
69066902 if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);
69076903 var limbs_buffer: [4]usize = undefined;
src/Sema.zig+92-76
......@@ -848,13 +848,12 @@ pub fn analyzeBodyBreak(
848848 block: *Block,
849849 body: []const Zir.Inst.Index,
850850) CompileError!?BreakData {
851 const mod = sema.mod;
852851 const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
853852 error.ComptimeBreak => sema.comptime_break_inst,
854853 else => |e| return e,
855854 };
856855 if (block.instructions.items.len != 0 and
857 sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn(mod))
856 sema.isNoReturn(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])))
858857 return null;
859858 const break_data = sema.code.instructions.items(.data)[break_inst].@"break";
860859 const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data;
......@@ -9671,9 +9670,9 @@ fn intCast(
96719670 // range to account for negative values.
96729671 const dest_range_val = if (wanted_info.signedness == .signed) range_val: {
96739672 const one = try mod.intValue(unsigned_operand_ty, 1);
9674 const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, sema.mod);
9673 const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, mod);
96759674 break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty);
9676 } else dest_max_val;
9675 } else try mod.getCoerced(dest_max_val, unsigned_operand_ty);
96779676 const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val);
96789677
96799678 const ok = if (is_vector) ok: {
......@@ -10791,7 +10790,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1079110790
1079210791 check_range: {
1079310792 if (operand_ty.zigTypeTag(mod) == .Int) {
10794 const min_int = try operand_ty.minInt(mod);
10793 const min_int = try operand_ty.minInt(mod, operand_ty);
1079510794 const max_int = try operand_ty.maxInt(mod, operand_ty);
1079610795 if (try range_set.spans(min_int, max_int, operand_ty)) {
1079710796 if (special_prong == .@"else") {
......@@ -11647,7 +11646,7 @@ const RangeSetUnhandledIterator = struct {
1164711646
1164811647 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {
1164911648 const mod = sema.mod;
11650 const min = try ty.minInt(mod);
11649 const min = try ty.minInt(mod, ty);
1165111650 const max = try ty.maxInt(mod, ty);
1165211651
1165311652 return RangeSetUnhandledIterator{
......@@ -12452,7 +12451,7 @@ fn zirShr(
1245212451 if (block.wantSafety()) {
1245312452 const bit_count = scalar_ty.intInfo(mod).bits;
1245412453 if (!std.math.isPowerOfTwo(bit_count)) {
12455 const bit_count_val = try mod.intValue(scalar_ty, bit_count);
12454 const bit_count_val = try mod.intValue(rhs_ty.scalarType(mod), bit_count);
1245612455
1245712456 const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: {
1245812457 const bit_count_inst = try sema.addConstant(rhs_ty, try sema.splat(rhs_ty, bit_count_val));
......@@ -13297,7 +13296,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1329713296 if (!lhs_val.isUndef(mod)) {
1329813297 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1329913298 const scalar_zero = switch (scalar_tag) {
13300 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13299 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1330113300 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
1330213301 else => unreachable,
1330313302 };
......@@ -13437,7 +13436,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1343713436 } else {
1343813437 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1343913438 const scalar_zero = switch (scalar_tag) {
13440 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13439 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1344113440 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
1344213441 else => unreachable,
1344313442 };
......@@ -13520,7 +13519,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1352013519 const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs);
1352113520
1352213521 const scalar_zero = switch (scalar_tag) {
13523 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13522 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1352413523 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
1352513524 else => unreachable,
1352613525 };
......@@ -13608,7 +13607,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1360813607 if (!lhs_val.isUndef(mod)) {
1360913608 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1361013609 const scalar_zero = switch (scalar_tag) {
13611 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13610 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1361213611 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
1361313612 else => unreachable,
1361413613 };
......@@ -13725,7 +13724,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1372513724 if (!lhs_val.isUndef(mod)) {
1372613725 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1372713726 const scalar_zero = switch (scalar_tag) {
13728 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13727 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1372913728 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
1373013729 else => unreachable,
1373113730 };
......@@ -13805,7 +13804,7 @@ fn addDivIntOverflowSafety(
1380513804 return;
1380613805 }
1380713806
13808 const min_int = try resolved_type.minInt(mod);
13807 const min_int = try resolved_type.minInt(mod, resolved_type);
1380913808 const neg_one_scalar = try mod.intValue(lhs_scalar_ty, -1);
1381013809 const neg_one = try sema.splat(resolved_type, neg_one_scalar);
1381113810
......@@ -13881,7 +13880,7 @@ fn addDivByZeroSafety(
1388113880 const scalar_zero = if (is_int)
1388213881 try mod.intValue(resolved_type.scalarType(mod), 0)
1388313882 else
13884 try mod.floatValue(resolved_type.scalarType(mod), 0);
13883 try mod.floatValue(resolved_type.scalarType(mod), 0.0);
1388513884 const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: {
1388613885 const zero_val = try sema.splat(resolved_type, scalar_zero);
1388713886 const zero = try sema.addConstant(resolved_type, zero_val);
......@@ -13967,7 +13966,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
1396713966 }
1396813967 if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) {
1396913968 const scalar_zero = switch (scalar_tag) {
13970 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
13969 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0),
1397113970 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
1397213971 else => unreachable,
1397313972 };
......@@ -14575,7 +14574,8 @@ fn analyzeArithmetic(
1457514574 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
1457614575 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
1457714576
14578 const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod);
14577 const scalar_type = resolved_type.scalarType(mod);
14578 const scalar_tag = scalar_type.zigTypeTag(mod);
1457914579
1458014580 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1458114581
......@@ -14797,8 +14797,13 @@ fn analyzeArithmetic(
1479714797 // the result is nan.
1479814798 // If either of the operands are nan, the result is nan.
1479914799 const scalar_zero = switch (scalar_tag) {
14800 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
14801 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14800 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),
14801 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),
14802 else => unreachable,
14803 };
14804 const scalar_one = switch (scalar_tag) {
14805 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0),
14806 .ComptimeInt, .Int => try mod.intValue(scalar_type, 1),
1480214807 else => unreachable,
1480314808 };
1480414809 if (maybe_lhs_val) |lhs_val| {
......@@ -14823,7 +14828,7 @@ fn analyzeArithmetic(
1482314828 const zero_val = try sema.splat(resolved_type, scalar_zero);
1482414829 return sema.addConstant(resolved_type, zero_val);
1482514830 }
14826 if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14831 if (try sema.compareAll(lhs_val, .eq, try sema.splat(resolved_type, scalar_one), resolved_type)) {
1482714832 return casted_rhs;
1482814833 }
1482914834 }
......@@ -14854,7 +14859,7 @@ fn analyzeArithmetic(
1485414859 const zero_val = try sema.splat(resolved_type, scalar_zero);
1485514860 return sema.addConstant(resolved_type, zero_val);
1485614861 }
14857 if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) {
14862 if (try sema.compareAll(rhs_val, .eq, try sema.splat(resolved_type, scalar_one), resolved_type)) {
1485814863 return casted_lhs;
1485914864 }
1486014865 if (maybe_lhs_val) |lhs_val| {
......@@ -14887,8 +14892,8 @@ fn analyzeArithmetic(
1488714892 // If either of the operands are one, result is the other operand.
1488814893 // If either of the operands are undefined, result is undefined.
1488914894 const scalar_zero = switch (scalar_tag) {
14890 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
14891 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14895 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),
14896 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),
1489214897 else => unreachable,
1489314898 };
1489414899 if (maybe_lhs_val) |lhs_val| {
......@@ -14931,8 +14936,8 @@ fn analyzeArithmetic(
1493114936 // If either of the operands are one, result is the other operand.
1493214937 // If either of the operands are undefined, result is undefined.
1493314938 const scalar_zero = switch (scalar_tag) {
14934 .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0),
14935 .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0),
14939 .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0),
14940 .ComptimeInt, .Int => try mod.intValue(scalar_type, 0),
1493614941 else => unreachable,
1493714942 };
1493814943 if (maybe_lhs_val) |lhs_val| {
......@@ -18817,7 +18822,10 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref {
1881718822 {
1881818823 return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty);
1881918824 }
18820 return sema.addConstant(opt_ptr_stack_trace_ty, Value.null);
18825 return sema.addConstant(opt_ptr_stack_trace_ty, (try mod.intern(.{ .opt = .{
18826 .ty = opt_ptr_stack_trace_ty.toIntern(),
18827 .val = .none,
18828 } })).toValue());
1882118829}
1882218830
1882318831fn zirFrame(
......@@ -20103,8 +20111,8 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
2010320111 if (block.wantSafety()) {
2010420112 const back = try block.addTyOp(.int_to_float, operand_ty, result);
2010520113 const diff = try block.addBinOp(.sub, operand, back);
20106 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)));
20107 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)));
20114 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.floatValue(operand_ty, 1.0)));
20115 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.floatValue(operand_ty, -1.0)));
2010820116 const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg);
2010920117 try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds);
2011020118 }
......@@ -22448,8 +22456,8 @@ fn analyzeMinMax(
2244822456
2244922457 // Compute the final bounds based on the runtime type and the comptime-known bound type
2245022458 const min_val = switch (air_tag) {
22451 .min => try unrefined_elem_ty.minInt(mod),
22452 .max => try comptime_elem_ty.minInt(mod), // @max(ct, rt) >= ct
22459 .min => try unrefined_elem_ty.minInt(mod, unrefined_elem_ty),
22460 .max => try comptime_elem_ty.minInt(mod, comptime_elem_ty), // @max(ct, rt) >= ct
2245322461 else => unreachable,
2245422462 };
2245522463 const max_val = switch (air_tag) {
......@@ -25996,7 +26004,7 @@ fn coerceExtra(
2599626004
2599726005 if (dest_info.sentinel) |dest_sent| {
2599826006 if (array_ty.sentinel(mod)) |inst_sent| {
25999 if (!dest_sent.eql(inst_sent, dst_elem_type, sema.mod)) {
26007 if (!dest_sent.eql(inst_sent, dst_elem_type, mod)) {
2600026008 in_memory_result = .{ .ptr_sentinel = .{
2600126009 .actual = inst_sent,
2600226010 .wanted = dest_sent,
......@@ -26115,7 +26123,7 @@ fn coerceExtra(
2611526123 if (inst_info.size == .Slice) {
2611626124 assert(dest_info.sentinel == null);
2611726125 if (inst_info.sentinel == null or
26118 !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, sema.mod))
26126 !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, mod))
2611926127 break :p;
2612026128
2612126129 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -26164,7 +26172,7 @@ fn coerceExtra(
2616426172 block,
2616526173 inst_src,
2616626174 "array literal requires address-of operator (&) to coerce to slice type '{}'",
26167 .{dest_ty.fmt(sema.mod)},
26175 .{dest_ty.fmt(mod)},
2616826176 );
2616926177 }
2617026178
......@@ -26190,7 +26198,7 @@ fn coerceExtra(
2619026198 // pointer to tuple to slice
2619126199 if (dest_info.mutable) {
2619226200 const err_msg = err_msg: {
26193 const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(sema.mod)});
26201 const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)});
2619426202 errdefer err_msg.deinit(sema.gpa);
2619526203 try sema.errNote(block, dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{});
2619626204 break :err_msg err_msg;
......@@ -26218,7 +26226,7 @@ fn coerceExtra(
2621826226 }
2621926227
2622026228 if (dest_info.sentinel == null or inst_info.sentinel == null or
26221 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, sema.mod))
26229 !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, mod))
2622226230 break :p;
2622326231
2622426232 const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty);
......@@ -26244,7 +26252,7 @@ fn coerceExtra(
2624426252 block,
2624526253 inst_src,
2624626254 "fractional component prevents float value '{}' from coercion to type '{}'",
26247 .{ val.fmtValue(inst_ty, sema.mod), dest_ty.fmt(sema.mod) },
26255 .{ val.fmtValue(inst_ty, mod), dest_ty.fmt(mod) },
2624826256 );
2624926257 }
2625026258 const result_val = try sema.floatToInt(block, inst_src, val, inst_ty, dest_ty);
......@@ -26258,7 +26266,7 @@ fn coerceExtra(
2625826266 // comptime-known integer to other number
2625926267 if (!(try sema.intFitsInType(val, dest_ty, null))) {
2626026268 if (!opts.report_err) return error.NotCoercible;
26261 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) });
26269 return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) });
2626226270 }
2626326271 return try sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty));
2626426272 }
......@@ -26296,12 +26304,12 @@ fn coerceExtra(
2629626304 }
2629726305 if (try sema.resolveMaybeUndefVal(inst)) |val| {
2629826306 const result_val = try val.floatCast(dest_ty, mod);
26299 if (!val.eql(result_val, inst_ty, sema.mod)) {
26307 if (!val.eql(try result_val.floatCast(inst_ty, mod), inst_ty, mod)) {
2630026308 return sema.fail(
2630126309 block,
2630226310 inst_src,
2630326311 "type '{}' cannot represent float value '{}'",
26304 .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) },
26312 .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) },
2630526313 );
2630626314 }
2630726315 return try sema.addConstant(dest_ty, result_val);
......@@ -26329,7 +26337,7 @@ fn coerceExtra(
2632926337 }
2633026338 break :int;
2633126339 };
26332 const result_val = try val.intToFloatAdvanced(sema.arena, inst_ty, dest_ty, sema.mod, sema);
26340 const result_val = try val.intToFloatAdvanced(sema.arena, inst_ty, dest_ty, mod, sema);
2633326341 // TODO implement this compile error
2633426342 //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty);
2633526343 //if (!int_again_val.eql(val, inst_ty, mod)) {
......@@ -26337,7 +26345,7 @@ fn coerceExtra(
2633726345 // block,
2633826346 // inst_src,
2633926347 // "type '{}' cannot represent integer value '{}'",
26340 // .{ dest_ty.fmt(sema.mod), val },
26348 // .{ dest_ty.fmt(mod), val },
2634126349 // );
2634226350 //}
2634326351 return try sema.addConstant(dest_ty, result_val);
......@@ -26359,7 +26367,7 @@ fn coerceExtra(
2635926367 block,
2636026368 inst_src,
2636126369 "no field named '{s}' in enum '{}'",
26362 .{ bytes, dest_ty.fmt(sema.mod) },
26370 .{ bytes, dest_ty.fmt(mod) },
2636326371 );
2636426372 errdefer msg.destroy(sema.gpa);
2636526373 try sema.addDeclaredHereNote(msg, dest_ty);
......@@ -26375,7 +26383,7 @@ fn coerceExtra(
2637526383 .Union => blk: {
2637626384 // union to its own tag type
2637726385 const union_tag_ty = inst_ty.unionTagType(mod) orelse break :blk;
26378 if (union_tag_ty.eql(dest_ty, sema.mod)) {
26386 if (union_tag_ty.eql(dest_ty, mod)) {
2637926387 return sema.unionToTag(block, dest_ty, inst, inst_src);
2638026388 }
2638126389 },
......@@ -26498,15 +26506,15 @@ fn coerceExtra(
2649826506 errdefer msg.destroy(sema.gpa);
2649926507
2650026508 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
26501 const src_decl = sema.mod.declPtr(sema.func.?.owner_decl);
26502 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "'noreturn' declared here", .{});
26509 const src_decl = mod.declPtr(sema.func.?.owner_decl);
26510 try mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "'noreturn' declared here", .{});
2650326511 break :msg msg;
2650426512 };
2650526513 return sema.failWithOwnedErrorMsg(msg);
2650626514 }
2650726515
2650826516 const msg = msg: {
26509 const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod) });
26517 const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(mod), inst_ty.fmt(mod) });
2651026518 errdefer msg.destroy(sema.gpa);
2651126519
2651226520 // E!T to T
......@@ -26528,18 +26536,18 @@ fn coerceExtra(
2652826536 try in_memory_result.report(sema, block, inst_src, msg);
2652926537
2653026538 // Add notes about function return type
26531 if (opts.is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) {
26539 if (opts.is_ret and mod.test_functions.get(sema.func.?.owner_decl) == null) {
2653226540 const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 };
26533 const src_decl = sema.mod.declPtr(sema.func.?.owner_decl);
26541 const src_decl = mod.declPtr(sema.func.?.owner_decl);
2653426542 if (inst_ty.isError(mod) and !dest_ty.isError(mod)) {
26535 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "function cannot return an error", .{});
26543 try mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "function cannot return an error", .{});
2653626544 } else {
26537 try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "function return type declared here", .{});
26545 try mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "function return type declared here", .{});
2653826546 }
2653926547 }
2654026548
2654126549 if (try opts.param_src.get(sema)) |param_src| {
26542 try sema.mod.errNoteNonLazy(param_src, msg, "parameter type declared here", .{});
26550 try mod.errNoteNonLazy(param_src, msg, "parameter type declared here", .{});
2654326551 }
2654426552
2654526553 // TODO maybe add "cannot store an error in type '{}'" note
......@@ -26679,7 +26687,7 @@ const InMemoryCoercionResult = union(enum) {
2667926687 },
2668026688 .error_union_payload => |pair| {
2668126689 try sema.errNote(block, src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{
26682 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26690 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2668326691 });
2668426692 cur = pair.child;
2668526693 },
......@@ -26692,18 +26700,18 @@ const InMemoryCoercionResult = union(enum) {
2669226700 .array_sentinel => |sentinel| {
2669326701 if (sentinel.actual.toIntern() != .unreachable_value) {
2669426702 try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{
26695 sentinel.actual.fmtValue(sentinel.ty, sema.mod), sentinel.wanted.fmtValue(sentinel.ty, sema.mod),
26703 sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod),
2669626704 });
2669726705 } else {
2669826706 try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{
26699 sentinel.wanted.fmtValue(sentinel.ty, sema.mod),
26707 sentinel.wanted.fmtValue(sentinel.ty, mod),
2670026708 });
2670126709 }
2670226710 break;
2670326711 },
2670426712 .array_elem => |pair| {
2670526713 try sema.errNote(block, src, msg, "array element type '{}' cannot cast into array element type '{}'", .{
26706 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26714 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2670726715 });
2670826716 cur = pair.child;
2670926717 },
......@@ -26715,19 +26723,19 @@ const InMemoryCoercionResult = union(enum) {
2671526723 },
2671626724 .vector_elem => |pair| {
2671726725 try sema.errNote(block, src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{
26718 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26726 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2671926727 });
2672026728 cur = pair.child;
2672126729 },
2672226730 .optional_shape => |pair| {
2672326731 try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
26724 pair.actual.optionalChild(mod).fmt(sema.mod), pair.wanted.optionalChild(mod).fmt(sema.mod),
26732 pair.actual.optionalChild(mod).fmt(mod), pair.wanted.optionalChild(mod).fmt(mod),
2672526733 });
2672626734 break;
2672726735 },
2672826736 .optional_child => |pair| {
2672926737 try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{
26730 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26738 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2673126739 });
2673226740 cur = pair.child;
2673326741 },
......@@ -26792,7 +26800,7 @@ const InMemoryCoercionResult = union(enum) {
2679226800 },
2679326801 .fn_param => |param| {
2679426802 try sema.errNote(block, src, msg, "parameter {d} '{}' cannot cast into '{}'", .{
26795 param.index, param.actual.fmt(sema.mod), param.wanted.fmt(sema.mod),
26803 param.index, param.actual.fmt(mod), param.wanted.fmt(mod),
2679626804 });
2679726805 cur = param.child;
2679826806 },
......@@ -26802,13 +26810,13 @@ const InMemoryCoercionResult = union(enum) {
2680226810 },
2680326811 .fn_return_type => |pair| {
2680426812 try sema.errNote(block, src, msg, "return type '{}' cannot cast into return type '{}'", .{
26805 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26813 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2680626814 });
2680726815 cur = pair.child;
2680826816 },
2680926817 .ptr_child => |pair| {
2681026818 try sema.errNote(block, src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{
26811 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26819 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2681226820 });
2681326821 cur = pair.child;
2681426822 },
......@@ -26819,11 +26827,11 @@ const InMemoryCoercionResult = union(enum) {
2681926827 .ptr_sentinel => |sentinel| {
2682026828 if (sentinel.actual.toIntern() != .unreachable_value) {
2682126829 try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{
26822 sentinel.actual.fmtValue(sentinel.ty, sema.mod), sentinel.wanted.fmtValue(sentinel.ty, sema.mod),
26830 sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod),
2682326831 });
2682426832 } else {
2682526833 try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{
26826 sentinel.wanted.fmtValue(sentinel.ty, sema.mod),
26834 sentinel.wanted.fmtValue(sentinel.ty, mod),
2682726835 });
2682826836 }
2682926837 break;
......@@ -26847,11 +26855,11 @@ const InMemoryCoercionResult = union(enum) {
2684726855 const actual_allow_zero = pair.actual.ptrAllowsZero(mod);
2684826856 if (actual_allow_zero and !wanted_allow_zero) {
2684926857 try sema.errNote(block, src, msg, "'{}' could have null values which are illegal in type '{}'", .{
26850 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26858 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2685126859 });
2685226860 } else {
2685326861 try sema.errNote(block, src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{
26854 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26862 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2685526863 });
2685626864 }
2685726865 break;
......@@ -26877,13 +26885,13 @@ const InMemoryCoercionResult = union(enum) {
2687726885 },
2687826886 .double_ptr_to_anyopaque => |pair| {
2687926887 try sema.errNote(block, src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{
26880 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26888 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2688126889 });
2688226890 break;
2688326891 },
2688426892 .slice_to_anyopaque => |pair| {
2688526893 try sema.errNote(block, src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{
26886 pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod),
26894 pair.actual.fmt(mod), pair.wanted.fmt(mod),
2688726895 });
2688826896 try sema.errNote(block, src, msg, "consider using '.ptr'", .{});
2688926897 break;
......@@ -27616,25 +27624,24 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
2761627624 const mod = sema.mod;
2761727625 const array_ty = sema.typeOf(ptr).childType(mod);
2761827626 if (array_ty.zigTypeTag(mod) != .Array) return null;
27619 var ptr_inst = Air.refToIndex(ptr) orelse return null;
27627 var ptr_ref = ptr;
27628 var ptr_inst = Air.refToIndex(ptr_ref) orelse return null;
2762027629 const air_datas = sema.air_instructions.items(.data);
2762127630 const air_tags = sema.air_instructions.items(.tag);
27622 const prev_ptr = while (air_tags[ptr_inst] == .bitcast) {
27623 const prev_ptr = air_datas[ptr_inst].ty_op.operand;
27624 const prev_ptr_ty = sema.typeOf(prev_ptr);
27625 if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null;
27626 const prev_ptr_child_ty = prev_ptr_ty.childType(mod);
27627 if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr;
27628 ptr_inst = Air.refToIndex(prev_ptr) orelse return null;
27631 const vector_ty = while (air_tags[ptr_inst] == .bitcast) {
27632 ptr_ref = air_datas[ptr_inst].ty_op.operand;
27633 if (!sema.isKnownZigType(ptr_ref, .Pointer)) return null;
27634 const child_ty = sema.typeOf(ptr_ref).childType(mod);
27635 if (child_ty.zigTypeTag(mod) == .Vector) break child_ty;
27636 ptr_inst = Air.refToIndex(ptr_ref) orelse return null;
2762927637 } else return null;
2763027638
2763127639 // We have a pointer-to-array and a pointer-to-vector. If the elements and
2763227640 // lengths match, return the result.
27633 const vector_ty = sema.typeOf(prev_ptr).childType(mod);
2763427641 if (array_ty.childType(mod).eql(vector_ty.childType(mod), sema.mod) and
2763527642 array_ty.arrayLen(mod) == vector_ty.vectorLen(mod))
2763627643 {
27637 return prev_ptr;
27644 return ptr_ref;
2763827645 } else {
2763927646 return null;
2764027647 }
......@@ -34474,3 +34481,12 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool {
3447434481 };
3447534482 return sema.typeOf(ref).isNoReturn(sema.mod);
3447634483}
34484
34485/// Avoids crashing the compiler when asking if inferred allocations are known to be a certain type.
34486fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool {
34487 if (Air.refToIndex(ref)) |inst| switch (sema.air_instructions.items(.tag)[inst]) {
34488 .inferred_alloc, .inferred_alloc_comptime => return false,
34489 else => {},
34490 };
34491 return sema.typeOf(ref).zigTypeTag(sema.mod) == tag;
34492}
src/arch/x86_64/CodeGen.zig+1-1
......@@ -4895,7 +4895,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
48954895 });
48964896
48974897 const sign_val = switch (tag) {
4898 .neg => try vec_ty.minInt(mod),
4898 .neg => try vec_ty.minInt(mod, vec_ty),
48994899 .fabs => try vec_ty.maxInt(mod, vec_ty),
49004900 else => unreachable,
49014901 };
src/codegen/c.zig+1-1
......@@ -6723,7 +6723,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
67236723 },
67246724 .Max => switch (scalar_ty.zigTypeTag(mod)) {
67256725 .Bool => try mod.intValue(scalar_ty, 0),
6726 .Int => try scalar_ty.minInt(mod),
6726 .Int => try scalar_ty.minInt(mod, scalar_ty),
67276727 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),
67286728 else => unreachable,
67296729 },
src/type.zig+9-9
......@@ -2865,23 +2865,23 @@ pub const Type = struct {
28652865 }
28662866
28672867 // Works for vectors and vectors of integers.
2868 pub fn minInt(ty: Type, mod: *Module) !Value {
2869 const scalar = try minIntScalar(ty.scalarType(mod), mod);
2868 pub fn minInt(ty: Type, mod: *Module, dest_ty: Type) !Value {
2869 const scalar = try minIntScalar(ty.scalarType(mod), mod, dest_ty);
28702870 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{
2871 .ty = ty.toIntern(),
2871 .ty = dest_ty.toIntern(),
28722872 .storage = .{ .repeated_elem = scalar.toIntern() },
28732873 } })).toValue() else scalar;
28742874 }
28752875
28762876 /// Asserts that the type is an integer.
2877 pub fn minIntScalar(ty: Type, mod: *Module) !Value {
2877 pub fn minIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {
28782878 const info = ty.intInfo(mod);
2879 if (info.signedness == .unsigned) return mod.intValue(ty, 0);
2880 if (info.bits == 0) return mod.intValue(ty, -1);
2879 if (info.signedness == .unsigned) return mod.intValue(dest_ty, 0);
2880 if (info.bits == 0) return mod.intValue(dest_ty, -1);
28812881
28822882 if (std.math.cast(u6, info.bits - 1)) |shift| {
28832883 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);
2884 return mod.intValue(Type.comptime_int, n);
2884 return mod.intValue(dest_ty, n);
28852885 }
28862886
28872887 var res = try std.math.big.int.Managed.init(mod.gpa);
......@@ -2889,7 +2889,7 @@ pub const Type = struct {
28892889
28902890 try res.setTwosCompIntLimit(.min, info.signedness, info.bits);
28912891
2892 return mod.intValue_big(Type.comptime_int, res.toConst());
2892 return mod.intValue_big(dest_ty, res.toConst());
28932893 }
28942894
28952895 // Works for vectors and vectors of integers.
......@@ -2897,7 +2897,7 @@ pub const Type = struct {
28972897 pub fn maxInt(ty: Type, mod: *Module, dest_ty: Type) !Value {
28982898 const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty);
28992899 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{
2900 .ty = ty.toIntern(),
2900 .ty = dest_ty.toIntern(),
29012901 .storage = .{ .repeated_elem = scalar.toIntern() },
29022902 } })).toValue() else scalar;
29032903 }
src/value.zig+5
......@@ -3166,6 +3166,11 @@ pub const Value = struct {
31663166 .len = undefined,
31673167 };
31683168 result_bigint.shiftLeft(lhs_bigint, shift);
3169 if (ty.toIntern() != .comptime_int_type) {
3170 const int_info = ty.intInfo(mod);
3171 result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits);
3172 }
3173
31693174 return mod.intValue_big(ty, result_bigint.toConst());
31703175 }
31713176