authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-07 15:07:28-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:42:29-07:00
loga5fb16959423005de999fb541d5d5e9aebb8e09e
tree87d4217e104cb9a1902ee34fb09a19fa5e583c96
parent8699cdc3dfcf3a3a6f09a64ea9c67be2459e1240

stage2: bug fixes related to Type/Value/InternPool


6 files changed, 92 insertions(+), 68 deletions(-)

src/Sema.zig+32-32
......@@ -1746,8 +1746,9 @@ pub fn resolveInst(sema: *Sema, zir_ref: Zir.Inst.Ref) !Air.Inst.Ref {
17461746 if (i < InternPool.static_len) return @intToEnum(Air.Inst.Ref, i);
17471747 // The last section of indexes refers to the map of ZIR => AIR.
17481748 const inst = sema.inst_map.get(i - InternPool.static_len).?;
1749 if (inst == .generic_poison) return error.GenericPoison;
17491750 const ty = sema.typeOf(inst);
1750 if (ty.isGenericPoison()) return error.GenericPoison;
1751 assert(!ty.isGenericPoison());
17511752 return inst;
17521753}
17531754
......@@ -2000,7 +2001,7 @@ fn resolveMaybeUndefValAllowVariablesMaybeRuntime(
20002001 .constant => {
20012002 const ty_pl = air_datas[i].ty_pl;
20022003 const val = sema.air_values.items[ty_pl.payload];
2003 if (val.tag() == .runtime_value) make_runtime.* = true;
2004 if (val.isRuntimeValue()) make_runtime.* = true;
20042005 if (val.isPtrToThreadLocal(sema.mod)) make_runtime.* = true;
20052006 return val;
20062007 },
......@@ -9688,7 +9689,7 @@ fn intCast(
96889689 // range shrinkage
96899690 // requirement: int value fits into target type
96909691 if (wanted_value_bits < actual_value_bits) {
9691 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod);
9692 const dest_max_val_scalar = try dest_scalar_ty.maxIntScalar(mod, operand_ty);
96929693 const dest_max_val = if (is_vector)
96939694 try Value.Tag.repeated.create(sema.arena, dest_max_val_scalar)
96949695 else
......@@ -10831,7 +10832,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1083110832 defer arena.deinit();
1083210833
1083310834 const min_int = try operand_ty.minInt(arena.allocator(), mod);
10834 const max_int = try operand_ty.maxIntScalar(mod);
10835 const max_int = try operand_ty.maxIntScalar(mod, Type.comptime_int);
1083510836 if (try range_set.spans(min_int, max_int, operand_ty)) {
1083610837 if (special_prong == .@"else") {
1083710838 return sema.fail(
......@@ -11683,7 +11684,7 @@ const RangeSetUnhandledIterator = struct {
1168311684 fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator {
1168411685 const mod = sema.mod;
1168511686 const min = try ty.minInt(sema.arena, mod);
11686 const max = try ty.maxIntScalar(mod);
11687 const max = try ty.maxIntScalar(mod, Type.comptime_int);
1168711688
1168811689 return RangeSetUnhandledIterator{
1168911690 .sema = sema,
......@@ -12294,7 +12295,7 @@ fn zirShl(
1229412295 {
1229512296 const max_int = try sema.addConstant(
1229612297 lhs_ty,
12297 try lhs_ty.maxInt(sema.arena, mod),
12298 try lhs_ty.maxInt(sema.arena, mod, lhs_ty),
1229812299 );
1229912300 const rhs_limited = try sema.analyzeMinMax(block, rhs_src, .min, &.{ rhs, max_int }, &.{ rhs_src, rhs_src });
1230012301 break :rhs try sema.intCast(block, src, lhs_ty, rhs_src, rhs_limited, rhs_src, false);
......@@ -16503,7 +16504,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1650316504 else
1650416505 try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i});
1650516506 const new_decl = try anon_decl.finish(
16506 try Type.array(anon_decl.arena(), bytes.len, try mod.intValue(Type.u8, 0), Type.u8, mod),
16507 try Type.array(anon_decl.arena(), bytes.len, Value.zero_u8, Type.u8, mod),
1650716508 try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
1650816509 0, // default alignment
1650916510 );
......@@ -22202,8 +22203,8 @@ fn analyzeMinMax(
2220222203 else => unreachable,
2220322204 };
2220422205 const max_val = switch (air_tag) {
22205 .min => try comptime_elem_ty.maxInt(sema.arena, mod), // @min(ct, rt) <= ct
22206 .max => try unrefined_elem_ty.maxInt(sema.arena, mod),
22206 .min => try comptime_elem_ty.maxInt(sema.arena, mod, Type.comptime_int), // @min(ct, rt) <= ct
22207 .max => try unrefined_elem_ty.maxInt(sema.arena, mod, Type.comptime_int),
2220722208 else => unreachable,
2220822209 };
2220922210
......@@ -27931,33 +27932,32 @@ fn beginComptimePtrMutation(
2793127932 switch (parent.pointee) {
2793227933 .direct => |val_ptr| {
2793327934 const payload_ty = parent.ty.errorUnionPayload();
27934 switch (val_ptr.tag()) {
27935 else => {
27936 // An error union has been initialized to undefined at comptime and now we
27937 // are for the first time setting the payload. We must change the
27938 // representation of the error union from `undef` to `opt_payload`.
27939 const arena = parent.beginArena(sema.mod);
27940 defer parent.finishArena(sema.mod);
27935 if (val_ptr.ip_index == .none and val_ptr.tag() == .eu_payload) {
27936 return ComptimePtrMutationKit{
27937 .decl_ref_mut = parent.decl_ref_mut,
27938 .pointee = .{ .direct = &val_ptr.castTag(.eu_payload).?.data },
27939 .ty = payload_ty,
27940 };
27941 } else {
27942 // An error union has been initialized to undefined at comptime and now we
27943 // are for the first time setting the payload. We must change the
27944 // representation of the error union from `undef` to `opt_payload`.
27945 const arena = parent.beginArena(sema.mod);
27946 defer parent.finishArena(sema.mod);
2794127947
27942 const payload = try arena.create(Value.Payload.SubValue);
27943 payload.* = .{
27944 .base = .{ .tag = .eu_payload },
27945 .data = Value.undef,
27946 };
27948 const payload = try arena.create(Value.Payload.SubValue);
27949 payload.* = .{
27950 .base = .{ .tag = .eu_payload },
27951 .data = Value.undef,
27952 };
2794727953
27948 val_ptr.* = Value.initPayload(&payload.base);
27954 val_ptr.* = Value.initPayload(&payload.base);
2794927955
27950 return ComptimePtrMutationKit{
27951 .decl_ref_mut = parent.decl_ref_mut,
27952 .pointee = .{ .direct = &payload.data },
27953 .ty = payload_ty,
27954 };
27955 },
27956 .eu_payload => return ComptimePtrMutationKit{
27956 return ComptimePtrMutationKit{
2795727957 .decl_ref_mut = parent.decl_ref_mut,
27958 .pointee = .{ .direct = &val_ptr.castTag(.eu_payload).?.data },
27958 .pointee = .{ .direct = &payload.data },
2795927959 .ty = payload_ty,
27960 },
27960 };
2796127961 }
2796227962 },
2796327963 .bad_decl_ty, .bad_ptr_ty => return parent,
......@@ -33225,7 +33225,7 @@ fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref {
3322533225
3322633226pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref {
3322733227 const gpa = sema.gpa;
33228 if (val.ip_index != .none) {
33228 if (val.ip_index != .none and val.ip_index != .null_value) {
3322933229 if (@enumToInt(val.ip_index) < Air.ref_start_index)
3323033230 return @intToEnum(Air.Inst.Ref, @enumToInt(val.ip_index));
3323133231 try sema.air_instructions.append(gpa, .{
src/arch/x86_64/CodeGen.zig+1-1
......@@ -4915,7 +4915,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
49154915
49164916 const sign_val = switch (tag) {
49174917 .neg => try vec_ty.minInt(stack.get(), mod),
4918 .fabs => try vec_ty.maxInt(stack.get(), mod),
4918 .fabs => try vec_ty.maxInt(stack.get(), mod, vec_ty),
49194919 else => unreachable,
49204920 };
49214921
src/codegen/c.zig+4-4
......@@ -3542,7 +3542,7 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue {
35423542 try v.elem(f, writer);
35433543 } else switch (dest_int_info.signedness) {
35443544 .unsigned => {
3545 const mask_val = try inst_scalar_ty.maxIntScalar(mod);
3545 const mask_val = try inst_scalar_ty.maxIntScalar(mod, scalar_ty);
35463546 try writer.writeAll("zig_and_");
35473547 try f.object.dg.renderTypeForBuiltinFnName(writer, scalar_ty);
35483548 try writer.writeByte('(');
......@@ -6681,13 +6681,13 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
66816681 .And => switch (scalar_ty.zigTypeTag(mod)) {
66826682 .Bool => try mod.intValue(Type.comptime_int, 1),
66836683 else => switch (scalar_ty.intInfo(mod).signedness) {
6684 .unsigned => try scalar_ty.maxIntScalar(mod),
6684 .unsigned => try scalar_ty.maxIntScalar(mod, scalar_ty),
66856685 .signed => try mod.intValue(scalar_ty, -1),
66866686 },
66876687 },
66886688 .Min => switch (scalar_ty.zigTypeTag(mod)) {
6689 .Bool => try mod.intValue(Type.comptime_int, 1),
6690 .Int => try scalar_ty.maxIntScalar(mod),
6689 .Bool => Value.one_comptime_int,
6690 .Int => try scalar_ty.maxIntScalar(mod, scalar_ty),
66916691 .Float => try Value.floatToValue(std.math.nan(f128), stack.get(), scalar_ty, target),
66926692 else => unreachable,
66936693 },
src/codegen/llvm.zig+17-11
......@@ -3570,15 +3570,21 @@ pub const DeclGen = struct {
35703570 },
35713571 .ErrorSet => {
35723572 const llvm_ty = try dg.lowerType(Type.anyerror);
3573 switch (tv.val.tag()) {
3574 .@"error" => {
3575 const err_name = tv.val.castTag(.@"error").?.data.name;
3576 const kv = try dg.module.getErrorValue(err_name);
3577 return llvm_ty.constInt(kv.value, .False);
3573 switch (tv.val.ip_index) {
3574 .none => switch (tv.val.tag()) {
3575 .@"error" => {
3576 const err_name = tv.val.castTag(.@"error").?.data.name;
3577 const kv = try dg.module.getErrorValue(err_name);
3578 return llvm_ty.constInt(kv.value, .False);
3579 },
3580 else => {
3581 // In this case we are rendering an error union which has a 0 bits payload.
3582 return llvm_ty.constNull();
3583 },
35783584 },
3579 else => {
3580 // In this case we are rendering an error union which has a 0 bits payload.
3581 return llvm_ty.constNull();
3585 else => switch (mod.intern_pool.indexToKey(tv.val.ip_index)) {
3586 .int => |int| return llvm_ty.constInt(int.storage.u64, .False),
3587 else => unreachable,
35823588 },
35833589 }
35843590 },
......@@ -3588,7 +3594,7 @@ pub const DeclGen = struct {
35883594
35893595 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
35903596 // We use the error type directly as the type.
3591 const err_val = if (!is_pl) tv.val else try mod.intValue(Type.anyerror, 0);
3597 const err_val = if (!is_pl) tv.val else try mod.intValue(Type.err_int, 0);
35923598 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });
35933599 }
35943600
......@@ -3596,7 +3602,7 @@ pub const DeclGen = struct {
35963602 const error_align = Type.anyerror.abiAlignment(mod);
35973603 const llvm_error_value = try dg.lowerValue(.{
35983604 .ty = Type.anyerror,
3599 .val = if (is_pl) try mod.intValue(Type.anyerror, 0) else tv.val,
3605 .val = if (is_pl) try mod.intValue(Type.err_int, 0) else tv.val,
36003606 });
36013607 const llvm_payload_value = try dg.lowerValue(.{
36023608 .ty = payload_type,
......@@ -6873,7 +6879,7 @@ pub const FuncGen = struct {
68736879 const err_union_ty = self.typeOf(ty_op.operand).childType(mod);
68746880
68756881 const payload_ty = err_union_ty.errorUnionPayload();
6876 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.anyerror, 0) });
6882 const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = try mod.intValue(Type.err_int, 0) });
68776883 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
68786884 _ = self.builder.buildStore(non_error_val, operand);
68796885 return operand;
src/type.zig+29-19
......@@ -4382,8 +4382,9 @@ pub const Type = struct {
43824382 }
43834383
43844384 // Works for vectors and vectors of integers.
4385 pub fn maxInt(ty: Type, arena: Allocator, mod: *Module) !Value {
4386 const scalar = try maxIntScalar(ty.scalarType(mod), mod);
4385 /// The returned Value will have type dest_ty.
4386 pub fn maxInt(ty: Type, arena: Allocator, mod: *Module, dest_ty: Type) !Value {
4387 const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty);
43874388 if (ty.zigTypeTag(mod) == .Vector and scalar.tag() != .the_only_possible_value) {
43884389 return Value.Tag.repeated.create(arena, scalar);
43894390 } else {
......@@ -4391,18 +4392,18 @@ pub const Type = struct {
43914392 }
43924393 }
43934394
4394 /// Asserts that the type is an integer.
4395 pub fn maxIntScalar(ty: Type, mod: *Module) !Value {
4395 /// The returned Value will have type dest_ty.
4396 pub fn maxIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {
43964397 const info = ty.intInfo(mod);
43974398
43984399 switch (info.bits) {
43994400 0 => return switch (info.signedness) {
4400 .signed => mod.intValue(ty, -1),
4401 .unsigned => mod.intValue(ty, 0),
4401 .signed => try mod.intValue(dest_ty, -1),
4402 .unsigned => try mod.intValue(dest_ty, 0),
44024403 },
44034404 1 => return switch (info.signedness) {
4404 .signed => mod.intValue(ty, 0),
4405 .unsigned => mod.intValue(ty, 0),
4405 .signed => try mod.intValue(dest_ty, 0),
4406 .unsigned => try mod.intValue(dest_ty, 1),
44064407 },
44074408 else => {},
44084409 }
......@@ -4410,11 +4411,11 @@ pub const Type = struct {
44104411 if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) {
44114412 .signed => {
44124413 const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift);
4413 return mod.intValue(Type.comptime_int, n);
4414 return mod.intValue(dest_ty, n);
44144415 },
44154416 .unsigned => {
44164417 const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift);
4417 return mod.intValue(Type.comptime_int, n);
4418 return mod.intValue(dest_ty, n);
44184419 },
44194420 };
44204421
......@@ -4423,7 +4424,7 @@ pub const Type = struct {
44234424
44244425 try res.setTwosCompIntLimit(.max, info.signedness, info.bits);
44254426
4426 return mod.intValue_big(Type.comptime_int, res.toConst());
4427 return mod.intValue_big(dest_ty, res.toConst());
44274428 }
44284429
44294430 /// Asserts the type is an enum or a union.
......@@ -5068,6 +5069,7 @@ pub const Type = struct {
50685069
50695070 pub fn isSimpleTuple(ty: Type) bool {
50705071 return switch (ty.ip_index) {
5072 .empty_struct => true,
50715073 .none => switch (ty.tag()) {
50725074 .tuple, .empty_struct_literal => true,
50735075 else => false,
......@@ -5077,21 +5079,29 @@ pub const Type = struct {
50775079 }
50785080
50795081 pub fn isSimpleTupleOrAnonStruct(ty: Type) bool {
5080 return switch (ty.tag()) {
5081 .tuple, .empty_struct_literal, .anon_struct => true,
5082 return switch (ty.ip_index) {
5083 .empty_struct => true,
5084 .none => switch (ty.tag()) {
5085 .tuple, .empty_struct_literal, .anon_struct => true,
5086 else => false,
5087 },
50825088 else => false,
50835089 };
50845090 }
50855091
50865092 // Only allowed for simple tuple types
50875093 pub fn tupleFields(ty: Type) Payload.Tuple.Data {
5088 return switch (ty.tag()) {
5089 .tuple => ty.castTag(.tuple).?.data,
5090 .anon_struct => .{
5091 .types = ty.castTag(.anon_struct).?.data.types,
5092 .values = ty.castTag(.anon_struct).?.data.values,
5094 return switch (ty.ip_index) {
5095 .empty_struct => .{ .types = &.{}, .values = &.{} },
5096 .none => switch (ty.tag()) {
5097 .tuple => ty.castTag(.tuple).?.data,
5098 .anon_struct => .{
5099 .types = ty.castTag(.anon_struct).?.data.types,
5100 .values = ty.castTag(.anon_struct).?.data.values,
5101 },
5102 .empty_struct_literal => .{ .types = &.{}, .values = &.{} },
5103 else => unreachable,
50935104 },
5094 .empty_struct_literal => .{ .types = &.{}, .values = &.{} },
50955105 else => unreachable,
50965106 };
50975107 }
src/value.zig+9-1
......@@ -2625,6 +2625,10 @@ pub const Value = struct {
26252625 }
26262626 }
26272627
2628 pub fn isRuntimeValue(val: Value) bool {
2629 return val.ip_index == .none and val.tag() == .runtime_value;
2630 }
2631
26282632 pub fn tagIsVariable(val: Value) bool {
26292633 return val.ip_index == .none and val.tag() == .variable;
26302634 }
......@@ -3402,7 +3406,7 @@ pub const Value = struct {
34023406 if (lhs.isUndef() or rhs.isUndef()) return Value.undef;
34033407
34043408 const anded = try bitwiseAnd(lhs, rhs, ty, arena, mod);
3405 const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod);
3409 const all_ones = if (ty.isSignedInt(mod)) try mod.intValue(ty, -1) else try ty.maxIntScalar(mod, ty);
34063410 return bitwiseXor(anded, all_ones, ty, arena, mod);
34073411 }
34083412
......@@ -5152,6 +5156,10 @@ pub const Value = struct {
51525156 pub const BigIntSpace = InternPool.Key.Int.Storage.BigIntSpace;
51535157
51545158 pub const zero_usize: Value = .{ .ip_index = .zero_usize, .legacy = undefined };
5159 pub const zero_u8: Value = .{ .ip_index = .zero_u8, .legacy = undefined };
5160 pub const zero_comptime_int: Value = .{ .ip_index = .zero, .legacy = undefined };
5161 pub const one_comptime_int: Value = .{ .ip_index = .one, .legacy = undefined };
5162 pub const negative_one_comptime_int: Value = .{ .ip_index = .negative_one, .legacy = undefined };
51555163 pub const undef: Value = .{ .ip_index = .undef, .legacy = undefined };
51565164 pub const float_zero: Value = .{ .ip_index = .zero, .legacy = undefined }; // TODO: replace this!
51575165 pub const @"void": Value = .{ .ip_index = .void_value, .legacy = undefined };