authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-25 23:48:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:55-07:00
log9afa97418350a51d8e27f1df903d8034507254ce
tree5ac1ff91beb66d9184a4cf1ab8485289e553f187
parent9a738c0be54c9bda0e57de9da84f86fc73bd5198

InternPool: fix enough crashes to run `build-obj` on a simple program


7 files changed, 228 insertions(+), 115 deletions(-)

src/InternPool.zig+34-23
......@@ -2298,7 +2298,7 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
22982298 ip.* = undefined;
22992299}
23002300
2301pub fn indexToKey(ip: InternPool, index: Index) Key {
2301pub fn indexToKey(ip: *const InternPool, index: Index) Key {
23022302 assert(index != .none);
23032303 const item = ip.items.get(@enumToInt(index));
23042304 const data = item.data;
......@@ -2361,7 +2361,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
23612361
23622362 .type_slice => {
23632363 const ptr_type_index = @intToEnum(Index, data);
2364 var result = indexToKey(ip, ptr_type_index).ptr_type;
2364 var result = ip.indexToKey(ptr_type_index).ptr_type;
23652365 result.size = .Slice;
23662366 return .{ .ptr_type = result };
23672367 },
......@@ -2454,9 +2454,9 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
24542454 .values_map = .none,
24552455 } };
24562456 },
2457 .type_enum_explicit => indexToKeyEnum(ip, data, .explicit),
2458 .type_enum_nonexhaustive => indexToKeyEnum(ip, data, .nonexhaustive),
2459 .type_function => .{ .func_type = indexToKeyFuncType(ip, data) },
2457 .type_enum_explicit => ip.indexToKeyEnum(data, .explicit),
2458 .type_enum_nonexhaustive => ip.indexToKeyEnum(data, .nonexhaustive),
2459 .type_function => .{ .func_type = ip.indexToKeyFuncType(data) },
24602460
24612461 .undef => .{ .undef = @intToEnum(Index, data) },
24622462 .runtime_value => {
......@@ -2591,8 +2591,8 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
25912591 .ty = .comptime_int_type,
25922592 .storage = .{ .i64 = @bitCast(i32, data) },
25932593 } },
2594 .int_positive => indexToKeyBigInt(ip, data, true),
2595 .int_negative => indexToKeyBigInt(ip, data, false),
2594 .int_positive => ip.indexToKeyBigInt(data, true),
2595 .int_negative => ip.indexToKeyBigInt(data, false),
25962596 .int_small => {
25972597 const info = ip.extraData(IntSmall, data);
25982598 return .{ .int = .{
......@@ -3430,22 +3430,25 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
34303430 .data = try ip.addExtra(gpa, err),
34313431 }),
34323432
3433 .error_union => |error_union| ip.items.appendAssumeCapacity(switch (error_union.val) {
3434 .err_name => |err_name| .{
3435 .tag = .error_union_error,
3436 .data = try ip.addExtra(gpa, Key.Error{
3437 .ty = error_union.ty,
3438 .name = err_name,
3439 }),
3440 },
3441 .payload => |payload| .{
3442 .tag = .error_union_payload,
3443 .data = try ip.addExtra(gpa, TypeValue{
3444 .ty = error_union.ty,
3445 .val = payload,
3446 }),
3447 },
3448 }),
3433 .error_union => |error_union| {
3434 assert(ip.indexToKey(error_union.ty) == .error_union_type);
3435 ip.items.appendAssumeCapacity(switch (error_union.val) {
3436 .err_name => |err_name| .{
3437 .tag = .error_union_error,
3438 .data = try ip.addExtra(gpa, Key.Error{
3439 .ty = error_union.ty,
3440 .name = err_name,
3441 }),
3442 },
3443 .payload => |payload| .{
3444 .tag = .error_union_payload,
3445 .data = try ip.addExtra(gpa, TypeValue{
3446 .ty = error_union.ty,
3447 .val = payload,
3448 }),
3449 },
3450 });
3451 },
34493452
34503453 .enum_literal => |enum_literal| ip.items.appendAssumeCapacity(.{
34513454 .tag = .enum_literal,
......@@ -4191,6 +4194,7 @@ pub fn sliceLen(ip: InternPool, i: Index) Index {
41914194/// * ptr <=> ptr
41924195/// * null_value => opt
41934196/// * payload => opt
4197/// * error set <=> error set
41944198pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Allocator.Error!Index {
41954199 const old_ty = ip.typeOf(val);
41964200 if (old_ty == new_ty) return val;
......@@ -4230,6 +4234,13 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
42304234 } }),
42314235 else => {},
42324236 },
4237 .err => |err| switch (ip.indexToKey(new_ty)) {
4238 .error_set_type, .inferred_error_set_type => return ip.get(gpa, .{ .err = .{
4239 .ty = new_ty,
4240 .name = err.name,
4241 } }),
4242 else => {},
4243 },
42334244 else => {},
42344245 }
42354246 switch (ip.indexToKey(new_ty)) {
src/Liveness/Verify.zig+36-32
......@@ -61,10 +61,10 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
6161 .work_item_id,
6262 .work_group_size,
6363 .work_group_id,
64 => try self.verifyInst(inst, .{ .none, .none, .none }),
64 => try self.verifyInstOperands(inst, .{ .none, .none, .none }),
6565
6666 .trap, .unreach => {
67 try self.verifyInst(inst, .{ .none, .none, .none });
67 try self.verifyInstOperands(inst, .{ .none, .none, .none });
6868 // This instruction terminates the function, so everything should be dead
6969 if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst});
7070 },
......@@ -113,7 +113,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
113113 .c_va_copy,
114114 => {
115115 const ty_op = data[inst].ty_op;
116 try self.verifyInst(inst, .{ ty_op.operand, .none, .none });
116 try self.verifyInstOperands(inst, .{ ty_op.operand, .none, .none });
117117 },
118118 .is_null,
119119 .is_non_null,
......@@ -149,13 +149,13 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
149149 .c_va_end,
150150 => {
151151 const un_op = data[inst].un_op;
152 try self.verifyInst(inst, .{ un_op, .none, .none });
152 try self.verifyInstOperands(inst, .{ un_op, .none, .none });
153153 },
154154 .ret,
155155 .ret_load,
156156 => {
157157 const un_op = data[inst].un_op;
158 try self.verifyInst(inst, .{ un_op, .none, .none });
158 try self.verifyInstOperands(inst, .{ un_op, .none, .none });
159159 // This instruction terminates the function, so everything should be dead
160160 if (self.live.count() > 0) return invalid("%{}: instructions still alive", .{inst});
161161 },
......@@ -164,36 +164,36 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
164164 .wasm_memory_grow,
165165 => {
166166 const pl_op = data[inst].pl_op;
167 try self.verifyInst(inst, .{ pl_op.operand, .none, .none });
167 try self.verifyInstOperands(inst, .{ pl_op.operand, .none, .none });
168168 },
169169 .prefetch => {
170170 const prefetch = data[inst].prefetch;
171 try self.verifyInst(inst, .{ prefetch.ptr, .none, .none });
171 try self.verifyInstOperands(inst, .{ prefetch.ptr, .none, .none });
172172 },
173173 .reduce,
174174 .reduce_optimized,
175175 => {
176176 const reduce = data[inst].reduce;
177 try self.verifyInst(inst, .{ reduce.operand, .none, .none });
177 try self.verifyInstOperands(inst, .{ reduce.operand, .none, .none });
178178 },
179179 .union_init => {
180180 const ty_pl = data[inst].ty_pl;
181181 const extra = self.air.extraData(Air.UnionInit, ty_pl.payload).data;
182 try self.verifyInst(inst, .{ extra.init, .none, .none });
182 try self.verifyInstOperands(inst, .{ extra.init, .none, .none });
183183 },
184184 .struct_field_ptr, .struct_field_val => {
185185 const ty_pl = data[inst].ty_pl;
186186 const extra = self.air.extraData(Air.StructField, ty_pl.payload).data;
187 try self.verifyInst(inst, .{ extra.struct_operand, .none, .none });
187 try self.verifyInstOperands(inst, .{ extra.struct_operand, .none, .none });
188188 },
189189 .field_parent_ptr => {
190190 const ty_pl = data[inst].ty_pl;
191191 const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data;
192 try self.verifyInst(inst, .{ extra.field_ptr, .none, .none });
192 try self.verifyInstOperands(inst, .{ extra.field_ptr, .none, .none });
193193 },
194194 .atomic_load => {
195195 const atomic_load = data[inst].atomic_load;
196 try self.verifyInst(inst, .{ atomic_load.ptr, .none, .none });
196 try self.verifyInstOperands(inst, .{ atomic_load.ptr, .none, .none });
197197 },
198198
199199 // binary
......@@ -263,7 +263,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
263263 .memcpy,
264264 => {
265265 const bin_op = data[inst].bin_op;
266 try self.verifyInst(inst, .{ bin_op.lhs, bin_op.rhs, .none });
266 try self.verifyInstOperands(inst, .{ bin_op.lhs, bin_op.rhs, .none });
267267 },
268268 .add_with_overflow,
269269 .sub_with_overflow,
......@@ -277,48 +277,48 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
277277 => {
278278 const ty_pl = data[inst].ty_pl;
279279 const extra = self.air.extraData(Air.Bin, ty_pl.payload).data;
280 try self.verifyInst(inst, .{ extra.lhs, extra.rhs, .none });
280 try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none });
281281 },
282282 .shuffle => {
283283 const ty_pl = data[inst].ty_pl;
284284 const extra = self.air.extraData(Air.Shuffle, ty_pl.payload).data;
285 try self.verifyInst(inst, .{ extra.a, extra.b, .none });
285 try self.verifyInstOperands(inst, .{ extra.a, extra.b, .none });
286286 },
287287 .cmp_vector,
288288 .cmp_vector_optimized,
289289 => {
290290 const ty_pl = data[inst].ty_pl;
291291 const extra = self.air.extraData(Air.VectorCmp, ty_pl.payload).data;
292 try self.verifyInst(inst, .{ extra.lhs, extra.rhs, .none });
292 try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, .none });
293293 },
294294 .atomic_rmw => {
295295 const pl_op = data[inst].pl_op;
296296 const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data;
297 try self.verifyInst(inst, .{ pl_op.operand, extra.operand, .none });
297 try self.verifyInstOperands(inst, .{ pl_op.operand, extra.operand, .none });
298298 },
299299
300300 // ternary
301301 .select => {
302302 const pl_op = data[inst].pl_op;
303303 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
304 try self.verifyInst(inst, .{ pl_op.operand, extra.lhs, extra.rhs });
304 try self.verifyInstOperands(inst, .{ pl_op.operand, extra.lhs, extra.rhs });
305305 },
306306 .mul_add => {
307307 const pl_op = data[inst].pl_op;
308308 const extra = self.air.extraData(Air.Bin, pl_op.payload).data;
309 try self.verifyInst(inst, .{ extra.lhs, extra.rhs, pl_op.operand });
309 try self.verifyInstOperands(inst, .{ extra.lhs, extra.rhs, pl_op.operand });
310310 },
311311 .vector_store_elem => {
312312 const vector_store_elem = data[inst].vector_store_elem;
313313 const extra = self.air.extraData(Air.Bin, vector_store_elem.payload).data;
314 try self.verifyInst(inst, .{ vector_store_elem.vector_ptr, extra.lhs, extra.rhs });
314 try self.verifyInstOperands(inst, .{ vector_store_elem.vector_ptr, extra.lhs, extra.rhs });
315315 },
316316 .cmpxchg_strong,
317317 .cmpxchg_weak,
318318 => {
319319 const ty_pl = data[inst].ty_pl;
320320 const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data;
321 try self.verifyInst(inst, .{ extra.ptr, extra.expected_value, extra.new_value });
321 try self.verifyInstOperands(inst, .{ extra.ptr, extra.expected_value, extra.new_value });
322322 },
323323
324324 // big tombs
......@@ -332,7 +332,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
332332 for (elements) |element| {
333333 try self.verifyOperand(inst, element, bt.feed());
334334 }
335 try self.verifyInst(inst, .{ .none, .none, .none });
335 try self.verifyInst(inst);
336336 },
337337 .call, .call_always_tail, .call_never_tail, .call_never_inline => {
338338 const pl_op = data[inst].pl_op;
......@@ -347,7 +347,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
347347 for (args) |arg| {
348348 try self.verifyOperand(inst, arg, bt.feed());
349349 }
350 try self.verifyInst(inst, .{ .none, .none, .none });
350 try self.verifyInst(inst);
351351 },
352352 .assembly => {
353353 const ty_pl = data[inst].ty_pl;
......@@ -373,7 +373,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
373373 for (inputs) |input| {
374374 try self.verifyOperand(inst, input, bt.feed());
375375 }
376 try self.verifyInst(inst, .{ .none, .none, .none });
376 try self.verifyInst(inst);
377377 },
378378
379379 // control flow
......@@ -397,7 +397,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
397397
398398 for (cond_br_liveness.then_deaths) |death| try self.verifyDeath(inst, death);
399399
400 try self.verifyInst(inst, .{ .none, .none, .none });
400 try self.verifyInst(inst);
401401 },
402402 .try_ptr => {
403403 const ty_pl = data[inst].ty_pl;
......@@ -419,7 +419,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
419419
420420 for (cond_br_liveness.then_deaths) |death| try self.verifyDeath(inst, death);
421421
422 try self.verifyInst(inst, .{ .none, .none, .none });
422 try self.verifyInst(inst);
423423 },
424424 .br => {
425425 const br = data[inst].br;
......@@ -431,7 +431,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
431431 } else {
432432 gop.value_ptr.* = try self.live.clone(self.gpa);
433433 }
434 try self.verifyInst(inst, .{ .none, .none, .none });
434 try self.verifyInst(inst);
435435 },
436436 .block => {
437437 const ty_pl = data[inst].ty_pl;
......@@ -462,7 +462,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
462462 try self.verifyMatchingLiveness(inst, live);
463463 }
464464
465 try self.verifyInst(inst, .{ .none, .none, .none });
465 try self.verifyInstOperands(inst, .{ .none, .none, .none });
466466 },
467467 .loop => {
468468 const ty_pl = data[inst].ty_pl;
......@@ -477,7 +477,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
477477 // The same stuff should be alive after the loop as before it
478478 try self.verifyMatchingLiveness(inst, live);
479479
480 try self.verifyInst(inst, .{ .none, .none, .none });
480 try self.verifyInstOperands(inst, .{ .none, .none, .none });
481481 },
482482 .cond_br => {
483483 const pl_op = data[inst].pl_op;
......@@ -500,7 +500,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
500500 for (cond_br_liveness.else_deaths) |death| try self.verifyDeath(inst, death);
501501 try self.verifyBody(else_body);
502502
503 try self.verifyInst(inst, .{ .none, .none, .none });
503 try self.verifyInst(inst);
504504 },
505505 .switch_br => {
506506 const pl_op = data[inst].pl_op;
......@@ -544,7 +544,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void {
544544 try self.verifyBody(else_body);
545545 }
546546
547 try self.verifyInst(inst, .{ .none, .none, .none });
547 try self.verifyInst(inst);
548548 },
549549 }
550550 }
......@@ -570,7 +570,7 @@ fn verifyOperand(self: *Verify, inst: Air.Inst.Index, op_ref: Air.Inst.Ref, dies
570570 }
571571}
572572
573fn verifyInst(
573fn verifyInstOperands(
574574 self: *Verify,
575575 inst: Air.Inst.Index,
576576 operands: [Liveness.bpi - 1]Air.Inst.Ref,
......@@ -579,6 +579,10 @@ fn verifyInst(
579579 const dies = self.liveness.operandDies(inst, @intCast(Liveness.OperandInt, operand_index));
580580 try self.verifyOperand(inst, operand, dies);
581581 }
582 try self.verifyInst(inst);
583}
584
585fn verifyInst(self: *Verify, inst: Air.Inst.Index) Error!void {
582586 if (self.air.instructions.items(.tag)[inst] == .interned) return;
583587 if (self.liveness.isUnused(inst)) {
584588 assert(!self.live.contains(inst));
src/Sema.zig+28-22
......@@ -16687,7 +16687,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1668716687 const new_decl_ty = try mod.arrayType(.{
1668816688 .len = bytes.len,
1668916689 .child = .u8_type,
16690 .sentinel = .zero_u8,
1669116690 });
1669216691 const new_decl = try anon_decl.finish(
1669316692 new_decl_ty,
......@@ -16698,7 +16697,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1669816697 0, // default alignment
1669916698 );
1670016699 break :v try mod.intern(.{ .ptr = .{
16701 .ty = .slice_const_u8_sentinel_0_type,
16700 .ty = .slice_const_u8_type,
1670216701 .addr = .{ .decl = new_decl },
1670316702 .len = (try mod.intValue(Type.usize, bytes.len)).toIntern(),
1670416703 } });
......@@ -23991,7 +23990,6 @@ fn panicWithMsg(
2399123990 msg_inst: Air.Inst.Ref,
2399223991) !void {
2399323992 const mod = sema.mod;
23994 const arena = sema.arena;
2399523993
2399623994 if (!mod.backendSupportsFeature(.panic_fn)) {
2399723995 _ = try block.addNoOp(.trap);
......@@ -24001,16 +23999,22 @@ fn panicWithMsg(
2400123999 const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace");
2400224000 const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty);
2400324001 const target = mod.getTarget();
24004 const ptr_stack_trace_ty = try Type.ptr(arena, mod, .{
24005 .pointee_type = stack_trace_ty,
24006 .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic
24002 const ptr_stack_trace_ty = try mod.ptrType(.{
24003 .elem_type = stack_trace_ty.toIntern(),
24004 .address_space = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic
2400724005 });
24008 const null_stack_trace = try sema.addConstant(
24009 try Type.optional(arena, ptr_stack_trace_ty, mod),
24010 Value.null,
24011 );
24012 const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value };
24013 try sema.callBuiltin(block, panic_fn, .auto, &args);
24006 const opt_ptr_stack_trace_ty = try mod.optionalType(ptr_stack_trace_ty.toIntern());
24007 const null_stack_trace = try sema.addConstant(opt_ptr_stack_trace_ty, (try mod.intern(.{ .opt = .{
24008 .ty = opt_ptr_stack_trace_ty.toIntern(),
24009 .val = .none,
24010 } })).toValue());
24011
24012 const opt_usize_ty = try mod.optionalType(.usize_type);
24013 const null_ret_addr = try sema.addConstant(opt_usize_ty, (try mod.intern(.{ .opt = .{
24014 .ty = opt_usize_ty.toIntern(),
24015 .val = .none,
24016 } })).toValue());
24017 try sema.callBuiltin(block, panic_fn, .auto, &.{ msg_inst, null_stack_trace, null_ret_addr });
2401424018}
2401524019
2401624020fn panicUnwrapError(
......@@ -29395,13 +29399,10 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value {
2939529399
2939629400fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value {
2939729401 const mod = sema.mod;
29398 const val = opt_val orelse return Value.null;
29399 const ptr_val = try sema.refValue(block, ty, val);
29400 const result = try mod.intern(.{ .opt = .{
29401 .ty = (try mod.optionalType((try mod.singleConstPtrType(ty)).toIntern())).toIntern(),
29402 .val = ptr_val.toIntern(),
29403 } });
29404 return result.toValue();
29402 return (try mod.intern(.{ .opt = .{
29403 .ty = (try mod.optionalType((try mod.singleConstPtrType(Type.anyopaque)).toIntern())).toIntern(),
29404 .val = if (opt_val) |val| (try sema.refValue(block, ty, val)).toIntern() else .none,
29405 } })).toValue();
2940529406}
2940629407
2940729408fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref {
......@@ -30603,7 +30604,7 @@ fn wrapErrorUnionPayload(
3060330604 if (try sema.resolveMaybeUndefVal(coerced)) |val| {
3060430605 return sema.addConstant(dest_ty, (try mod.intern(.{ .error_union = .{
3060530606 .ty = dest_ty.toIntern(),
30606 .val = .{ .payload = val.toIntern() },
30607 .val = .{ .payload = try val.intern(dest_payload_ty, mod) },
3060730608 } })).toValue());
3060830609 }
3060930610 try sema.requireRuntimeBlock(block, inst_src, null);
......@@ -30647,7 +30648,12 @@ fn wrapErrorUnionSet(
3064730648 else => unreachable,
3064830649 },
3064930650 }
30650 return sema.addConstant(dest_ty, val);
30651 return sema.addConstant(dest_ty, (try mod.intern(.{ .error_union = .{
30652 .ty = dest_ty.toIntern(),
30653 .val = .{
30654 .err_name = mod.intern_pool.indexToKey(try val.intern(dest_err_set_ty, mod)).err.name,
30655 },
30656 } })).toValue());
3065130657 }
3065230658
3065330659 try sema.requireRuntimeBlock(block, inst_src, null);
......@@ -33325,7 +33331,7 @@ fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref {
3332533331}
3332633332
3332733333fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref {
33328 return sema.addConstant(ty, Value.undef);
33334 return sema.addConstant(ty, (try sema.mod.intern(.{ .undef = ty.toIntern() })).toValue());
3332933335}
3333033336
3333133337pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref {
src/codegen/llvm.zig+16-9
......@@ -3267,21 +3267,28 @@ pub const DeclGen = struct {
32673267 return llvm_ty.constInt(kv.value, .False);
32683268 },
32693269 .error_union => |error_union| {
3270 const err_tv: TypedValue = switch (error_union.val) {
3271 .err_name => |err_name| .{
3272 .ty = tv.ty.errorUnionSet(mod),
3273 .val = (try mod.intern(.{ .err = .{
3274 .ty = tv.ty.errorUnionSet(mod).toIntern(),
3275 .name = err_name,
3276 } })).toValue(),
3277 },
3278 .payload => .{
3279 .ty = Type.err_int,
3280 .val = try mod.intValue(Type.err_int, 0),
3281 },
3282 };
32703283 const payload_type = tv.ty.errorUnionPayload(mod);
3271 const is_pl = tv.val.errorUnionIsPayload(mod);
3272
32733284 if (!payload_type.hasRuntimeBitsIgnoreComptime(mod)) {
32743285 // We use the error type directly as the type.
3275 const err_val = if (!is_pl) tv.val else try mod.intValue(Type.err_int, 0);
3276 return dg.lowerValue(.{ .ty = Type.anyerror, .val = err_val });
3286 return dg.lowerValue(err_tv);
32773287 }
32783288
32793289 const payload_align = payload_type.abiAlignment(mod);
3280 const error_align = Type.anyerror.abiAlignment(mod);
3281 const llvm_error_value = try dg.lowerValue(.{
3282 .ty = Type.anyerror,
3283 .val = if (is_pl) try mod.intValue(Type.err_int, 0) else tv.val,
3284 });
3290 const error_align = err_tv.ty.abiAlignment(mod);
3291 const llvm_error_value = try dg.lowerValue(err_tv);
32853292 const llvm_payload_value = try dg.lowerValue(.{
32863293 .ty = payload_type,
32873294 .val = switch (error_union.val) {
src/print_air.zig+1-1
......@@ -703,7 +703,7 @@ const Writer = struct {
703703 const pl_op = w.air.instructions.items(.data)[inst].pl_op;
704704 try w.writeOperand(s, inst, 0, pl_op.operand);
705705 const name = w.air.nullTerminatedString(pl_op.payload);
706 try s.print(", {s}", .{name});
706 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
707707 }
708708
709709 fn writeCall(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/value.zig+112-28
......@@ -347,6 +347,43 @@ pub const Value = struct {
347347 pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
348348 if (val.ip_index != .none) return mod.intern_pool.getCoerced(mod.gpa, val.toIntern(), ty.toIntern());
349349 switch (val.tag()) {
350 .eu_payload => {
351 const pl = val.castTag(.eu_payload).?.data;
352 return mod.intern(.{ .error_union = .{
353 .ty = ty.toIntern(),
354 .val = .{ .payload = try pl.intern(ty.errorUnionPayload(mod), mod) },
355 } });
356 },
357 .opt_payload => {
358 const pl = val.castTag(.opt_payload).?.data;
359 return mod.intern(.{ .opt = .{
360 .ty = ty.toIntern(),
361 .val = try pl.intern(ty.optionalChild(mod), mod),
362 } });
363 },
364 .slice => {
365 const pl = val.castTag(.slice).?.data;
366 const ptr = try pl.ptr.intern(ty.optionalChild(mod), mod);
367 var ptr_key = mod.intern_pool.indexToKey(ptr).ptr;
368 assert(ptr_key.len == .none);
369 ptr_key.ty = ty.toIntern();
370 ptr_key.len = try pl.len.intern(Type.usize, mod);
371 return mod.intern(.{ .ptr = ptr_key });
372 },
373 .bytes => {
374 const pl = val.castTag(.bytes).?.data;
375 return mod.intern(.{ .aggregate = .{
376 .ty = ty.toIntern(),
377 .storage = .{ .bytes = pl },
378 } });
379 },
380 .repeated => {
381 const pl = val.castTag(.repeated).?.data;
382 return mod.intern(.{ .aggregate = .{
383 .ty = ty.toIntern(),
384 .storage = .{ .repeated_elem = try pl.intern(ty.childType(mod), mod) },
385 } });
386 },
350387 .aggregate => {
351388 const old_elems = val.castTag(.aggregate).?.data;
352389 const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len);
......@@ -372,24 +409,74 @@ pub const Value = struct {
372409 .val = try pl.val.intern(ty.unionFieldType(pl.tag, mod), mod),
373410 } });
374411 },
375 else => unreachable,
376412 }
377413 }
378414
379415 pub fn unintern(val: Value, arena: Allocator, mod: *Module) Allocator.Error!Value {
380 if (val.ip_index == .none) return val;
381 switch (mod.intern_pool.indexToKey(val.toIntern())) {
416 return if (val.ip_index == .none) val else switch (mod.intern_pool.indexToKey(val.toIntern())) {
417 .int_type,
418 .ptr_type,
419 .array_type,
420 .vector_type,
421 .opt_type,
422 .anyframe_type,
423 .error_union_type,
424 .simple_type,
425 .struct_type,
426 .anon_struct_type,
427 .union_type,
428 .opaque_type,
429 .enum_type,
430 .func_type,
431 .error_set_type,
432 .inferred_error_set_type,
433
434 .undef,
435 .runtime_value,
436 .simple_value,
437 .variable,
438 .extern_func,
439 .func,
440 .int,
441 .err,
442 .enum_literal,
443 .enum_tag,
444 .float,
445 => val,
446
447 .error_union => |error_union| switch (error_union.val) {
448 .err_name => val,
449 .payload => |payload| Tag.eu_payload.create(arena, payload.toValue()),
450 },
451
452 .ptr => |ptr| switch (ptr.len) {
453 .none => val,
454 else => |len| Tag.slice.create(arena, .{
455 .ptr = val.slicePtr(mod),
456 .len = len.toValue(),
457 }),
458 },
459
460 .opt => |opt| switch (opt.val) {
461 .none => val,
462 else => |payload| Tag.opt_payload.create(arena, payload.toValue()),
463 },
464
382465 .aggregate => |aggregate| switch (aggregate.storage) {
383 .bytes => |bytes| return Tag.bytes.create(arena, try arena.dupe(u8, bytes)),
466 .bytes => |bytes| Tag.bytes.create(arena, try arena.dupe(u8, bytes)),
384467 .elems => |old_elems| {
385468 const new_elems = try arena.alloc(Value, old_elems.len);
386469 for (new_elems, old_elems) |*new_elem, old_elem| new_elem.* = old_elem.toValue();
387470 return Tag.aggregate.create(arena, new_elems);
388471 },
389 .repeated_elem => |elem| return Tag.repeated.create(arena, elem.toValue()),
472 .repeated_elem => |elem| Tag.repeated.create(arena, elem.toValue()),
390473 },
391 else => return val,
392 }
474
475 .un => |un| Tag.@"union".create(arena, .{
476 .tag = un.tag.toValue(),
477 .val = un.val.toValue(),
478 }),
479 };
393480 }
394481
395482 pub fn toIntern(val: Value) InternPool.Index {
......@@ -1896,7 +1983,7 @@ pub const Value = struct {
18961983
18971984 /// Returns true if a Value is backed by a variable
18981985 pub fn isVariable(val: Value, mod: *Module) bool {
1899 return switch (mod.intern_pool.indexToKey(val.toIntern())) {
1986 return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {
19001987 .variable => true,
19011988 .ptr => |ptr| switch (ptr.addr) {
19021989 .decl => |decl_index| {
......@@ -1919,28 +2006,25 @@ pub const Value = struct {
19192006 }
19202007
19212008 pub fn isPtrToThreadLocal(val: Value, mod: *Module) bool {
1922 return switch (val.ip_index) {
1923 .none => false,
1924 else => switch (mod.intern_pool.indexToKey(val.toIntern())) {
1925 .variable => |variable| variable.is_threadlocal,
1926 .ptr => |ptr| switch (ptr.addr) {
1927 .decl => |decl_index| {
1928 const decl = mod.declPtr(decl_index);
1929 assert(decl.has_tv);
1930 return decl.val.isPtrToThreadLocal(mod);
1931 },
1932 .mut_decl => |mut_decl| {
1933 const decl = mod.declPtr(mut_decl.decl);
1934 assert(decl.has_tv);
1935 return decl.val.isPtrToThreadLocal(mod);
1936 },
1937 .int => false,
1938 .eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocal(mod),
1939 .comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocal(mod),
1940 .elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocal(mod),
2009 return val.ip_index != .none and switch (mod.intern_pool.indexToKey(val.toIntern())) {
2010 .variable => |variable| variable.is_threadlocal,
2011 .ptr => |ptr| switch (ptr.addr) {
2012 .decl => |decl_index| {
2013 const decl = mod.declPtr(decl_index);
2014 assert(decl.has_tv);
2015 return decl.val.isPtrToThreadLocal(mod);
19412016 },
1942 else => false,
2017 .mut_decl => |mut_decl| {
2018 const decl = mod.declPtr(mut_decl.decl);
2019 assert(decl.has_tv);
2020 return decl.val.isPtrToThreadLocal(mod);
2021 },
2022 .int => false,
2023 .eu_payload, .opt_payload => |base_ptr| base_ptr.toValue().isPtrToThreadLocal(mod),
2024 .comptime_field => |comptime_field| comptime_field.toValue().isPtrToThreadLocal(mod),
2025 .elem, .field => |base_index| base_index.base.toValue().isPtrToThreadLocal(mod),
19432026 },
2027 else => false,
19442028 };
19452029 }
19462030
tools/lldb_pretty_printers.py+1
......@@ -681,6 +681,7 @@ def __lldb_init_module(debugger, _=None):
681681 add(debugger, category='zig.stage2', regex=True, type=MultiArrayList_Entry('Air\\.Inst'), identifier='TagAndPayload', synth=True, inline_children=True, summary=True)
682682 add(debugger, category='zig.stage2', regex=True, type='^Air\\.Inst\\.Data\\.Data__struct_[1-9][0-9]*$', inline_children=True, summary=True)
683683 add(debugger, category='zig.stage2', type='Module.Decl::Module.Decl.Index', synth=True)
684 add(debugger, category='zig.stage2', type='Module.LazySrcLoc', identifier='zig_TaggedUnion', synth=True)
684685 add(debugger, category='zig.stage2', type='InternPool.Index', synth=True)
685686 add(debugger, category='zig.stage2', type='InternPool.Key', identifier='zig_TaggedUnion', synth=True)
686687 add(debugger, category='zig.stage2', type='InternPool.Key.Int.Storage', identifier='zig_TaggedUnion', synth=True)