mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
InternPool: make more use of NullTerminatedString.Slice
This should avoid the random pointer invalidation crashes. Closes #18954
This commit is contained in:
parent
0183b44bb1
commit
6f08e17229
23
src/Sema.zig
23
src/Sema.zig
@ -12619,8 +12619,9 @@ fn analyzeSwitchRuntimeBlock(
|
|||||||
operand_ty.fmt(mod),
|
operand_ty.fmt(mod),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (0..operand_ty.errorSetNames(mod).len) |i| {
|
const error_names = operand_ty.errorSetNames(mod);
|
||||||
const error_name = operand_ty.errorSetNames(mod)[i];
|
for (0..error_names.len) |name_index| {
|
||||||
|
const error_name = error_names.get(ip)[name_index];
|
||||||
if (seen_errors.contains(error_name)) continue;
|
if (seen_errors.contains(error_name)) continue;
|
||||||
cases_len += 1;
|
cases_len += 1;
|
||||||
|
|
||||||
@ -22362,8 +22363,9 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
|
|||||||
if (!operand_ty.isAnyError(mod) and operand_ty.errorSetIsEmpty(mod)) break :disjoint true;
|
if (!operand_ty.isAnyError(mod) and operand_ty.errorSetIsEmpty(mod)) break :disjoint true;
|
||||||
if (dest_ty.isAnyError(mod)) break :disjoint false;
|
if (dest_ty.isAnyError(mod)) break :disjoint false;
|
||||||
if (operand_ty.isAnyError(mod)) break :disjoint false;
|
if (operand_ty.isAnyError(mod)) break :disjoint false;
|
||||||
for (dest_ty.errorSetNames(mod)) |dest_err_name| {
|
const dest_err_names = dest_ty.errorSetNames(mod);
|
||||||
if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_name))
|
for (0..dest_err_names.len) |dest_err_index| {
|
||||||
|
if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_names.get(ip)[dest_err_index]))
|
||||||
break :disjoint false;
|
break :disjoint false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -22375,8 +22377,8 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
|
|||||||
|
|
||||||
_ = try sema.resolveInferredErrorSetTy(block, src, dest_ty.toIntern());
|
_ = try sema.resolveInferredErrorSetTy(block, src, dest_ty.toIntern());
|
||||||
_ = try sema.resolveInferredErrorSetTy(block, operand_src, operand_ty.toIntern());
|
_ = try sema.resolveInferredErrorSetTy(block, operand_src, operand_ty.toIntern());
|
||||||
for (dest_ty.errorSetNames(mod)) |dest_err_name| {
|
for (0..dest_err_names.len) |dest_err_index| {
|
||||||
if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_name))
|
if (Type.errorSetHasFieldIp(ip, operand_ty.toIntern(), dest_err_names.get(ip)[dest_err_index]))
|
||||||
break :disjoint false;
|
break :disjoint false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38780,17 +38782,18 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type {
|
|||||||
/// Asserts that lhs and rhs are both error sets and are resolved.
|
/// Asserts that lhs and rhs are both error sets and are resolved.
|
||||||
fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
|
fn errorSetMerge(sema: *Sema, lhs: Type, rhs: Type) !Type {
|
||||||
const mod = sema.mod;
|
const mod = sema.mod;
|
||||||
|
const ip = &mod.intern_pool;
|
||||||
const arena = sema.arena;
|
const arena = sema.arena;
|
||||||
const lhs_names = lhs.errorSetNames(mod);
|
const lhs_names = lhs.errorSetNames(mod);
|
||||||
const rhs_names = rhs.errorSetNames(mod);
|
const rhs_names = rhs.errorSetNames(mod);
|
||||||
var names: InferredErrorSet.NameMap = .{};
|
var names: InferredErrorSet.NameMap = .{};
|
||||||
try names.ensureUnusedCapacity(arena, lhs_names.len);
|
try names.ensureUnusedCapacity(arena, lhs_names.len);
|
||||||
|
|
||||||
for (lhs_names) |name| {
|
for (0..lhs_names.len) |lhs_index| {
|
||||||
names.putAssumeCapacityNoClobber(name, {});
|
names.putAssumeCapacityNoClobber(lhs_names.get(ip)[lhs_index], {});
|
||||||
}
|
}
|
||||||
for (rhs_names) |name| {
|
for (0..rhs_names.len) |rhs_index| {
|
||||||
try names.put(arena, name, {});
|
try names.put(arena, rhs_names.get(ip)[rhs_index], {});
|
||||||
}
|
}
|
||||||
|
|
||||||
return mod.errorSetFromUnsortedNames(names.keys());
|
return mod.errorSetFromUnsortedNames(names.keys());
|
||||||
|
|||||||
@ -7216,13 +7216,14 @@ fn airTagName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||||||
|
|
||||||
fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
|
fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
|
||||||
const mod = func.bin_file.base.comp.module.?;
|
const mod = func.bin_file.base.comp.module.?;
|
||||||
|
const ip = &mod.intern_pool;
|
||||||
const enum_decl_index = enum_ty.getOwnerDecl(mod);
|
const enum_decl_index = enum_ty.getOwnerDecl(mod);
|
||||||
|
|
||||||
var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
|
var arena_allocator = std.heap.ArenaAllocator.init(func.gpa);
|
||||||
defer arena_allocator.deinit();
|
defer arena_allocator.deinit();
|
||||||
const arena = arena_allocator.allocator();
|
const arena = arena_allocator.allocator();
|
||||||
|
|
||||||
const fqn = mod.intern_pool.stringToSlice(try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod));
|
const fqn = ip.stringToSlice(try mod.declPtr(enum_decl_index).getFullyQualifiedName(mod));
|
||||||
const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
|
const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn});
|
||||||
|
|
||||||
// check if we already generated code for this.
|
// check if we already generated code for this.
|
||||||
@ -7252,9 +7253,9 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
|
|||||||
|
|
||||||
// TODO: Make switch implementation generic so we can use a jump table for this when the tags are not sparse.
|
// TODO: Make switch implementation generic so we can use a jump table for this when the tags are not sparse.
|
||||||
// generate an if-else chain for each tag value as well as constant.
|
// generate an if-else chain for each tag value as well as constant.
|
||||||
for (enum_ty.enumFields(mod), 0..) |tag_name_ip, field_index_usize| {
|
const tag_names = enum_ty.enumFields(mod);
|
||||||
const field_index = @as(u32, @intCast(field_index_usize));
|
for (0..tag_names.len) |tag_index| {
|
||||||
const tag_name = mod.intern_pool.stringToSlice(tag_name_ip);
|
const tag_name = ip.stringToSlice(tag_names.get(ip)[tag_index]);
|
||||||
// for each tag name, create an unnamed const,
|
// for each tag name, create an unnamed const,
|
||||||
// and then get a pointer to its value.
|
// and then get a pointer to its value.
|
||||||
const name_ty = try mod.arrayType(.{
|
const name_ty = try mod.arrayType(.{
|
||||||
@ -7279,7 +7280,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
|
|||||||
try writer.writeByte(std.wasm.opcode(.local_get));
|
try writer.writeByte(std.wasm.opcode(.local_get));
|
||||||
try leb.writeULEB128(writer, @as(u32, 1));
|
try leb.writeULEB128(writer, @as(u32, 1));
|
||||||
|
|
||||||
const tag_val = try mod.enumValueFieldIndex(enum_ty, field_index);
|
const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));
|
||||||
const tag_value = try func.lowerConstant(tag_val, enum_ty);
|
const tag_value = try func.lowerConstant(tag_val, enum_ty);
|
||||||
|
|
||||||
switch (tag_value) {
|
switch (tag_value) {
|
||||||
@ -7372,6 +7373,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
|
|||||||
|
|
||||||
fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
||||||
const mod = func.bin_file.base.comp.module.?;
|
const mod = func.bin_file.base.comp.module.?;
|
||||||
|
const ip = &mod.intern_pool;
|
||||||
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
const ty_op = func.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
||||||
|
|
||||||
const operand = try func.resolveInst(ty_op.operand);
|
const operand = try func.resolveInst(ty_op.operand);
|
||||||
@ -7384,8 +7386,8 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
|
|||||||
|
|
||||||
var lowest: ?u32 = null;
|
var lowest: ?u32 = null;
|
||||||
var highest: ?u32 = null;
|
var highest: ?u32 = null;
|
||||||
for (names) |name| {
|
for (0..names.len) |name_index| {
|
||||||
const err_int = @as(Module.ErrorInt, @intCast(mod.global_error_set.getIndex(name).?));
|
const err_int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[name_index]).?);
|
||||||
if (lowest) |*l| {
|
if (lowest) |*l| {
|
||||||
if (err_int < l.*) {
|
if (err_int < l.*) {
|
||||||
l.* = err_int;
|
l.* = err_int;
|
||||||
|
|||||||
@ -2187,6 +2187,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
|
|||||||
|
|
||||||
fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
|
fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
|
||||||
const mod = self.bin_file.comp.module.?;
|
const mod = self.bin_file.comp.module.?;
|
||||||
|
const ip = &mod.intern_pool;
|
||||||
switch (lazy_sym.ty.zigTypeTag(mod)) {
|
switch (lazy_sym.ty.zigTypeTag(mod)) {
|
||||||
.Enum => {
|
.Enum => {
|
||||||
const enum_ty = lazy_sym.ty;
|
const enum_ty = lazy_sym.ty;
|
||||||
@ -2209,10 +2210,10 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
|
|||||||
try self.genLazySymbolRef(.lea, data_reg, .{ .kind = .const_data, .ty = enum_ty });
|
try self.genLazySymbolRef(.lea, data_reg, .{ .kind = .const_data, .ty = enum_ty });
|
||||||
|
|
||||||
var data_off: i32 = 0;
|
var data_off: i32 = 0;
|
||||||
for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, index_usize| {
|
const tag_names = enum_ty.enumFields(mod);
|
||||||
const index: u32 = @intCast(index_usize);
|
for (exitlude_jump_relocs, 0..) |*exitlude_jump_reloc, tag_index| {
|
||||||
const tag_name = mod.intern_pool.stringToSlice(enum_ty.enumFields(mod)[index_usize]);
|
const tag_name_len = ip.stringToSlice(tag_names.get(ip)[tag_index]).len;
|
||||||
const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
|
const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));
|
||||||
const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });
|
const tag_mcv = try self.genTypedValue(.{ .ty = enum_ty, .val = tag_val });
|
||||||
try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);
|
try self.genBinOpMir(.{ ._, .cmp }, enum_ty, enum_mcv, tag_mcv);
|
||||||
const skip_reloc = try self.asmJccReloc(.ne, undefined);
|
const skip_reloc = try self.asmJccReloc(.ne, undefined);
|
||||||
@ -2228,14 +2229,14 @@ fn genLazy(self: *Self, lazy_sym: link.File.LazySymbol) InnerError!void {
|
|||||||
.{ .reg = ret_reg },
|
.{ .reg = ret_reg },
|
||||||
8,
|
8,
|
||||||
Type.usize,
|
Type.usize,
|
||||||
.{ .immediate = tag_name.len },
|
.{ .immediate = tag_name_len },
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
|
|
||||||
exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);
|
exitlude_jump_reloc.* = try self.asmJmpReloc(undefined);
|
||||||
self.performReloc(skip_reloc);
|
self.performReloc(skip_reloc);
|
||||||
|
|
||||||
data_off += @intCast(tag_name.len + 1);
|
data_off += @intCast(tag_name_len + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
try self.airTrap();
|
try self.airTrap();
|
||||||
|
|||||||
@ -119,6 +119,7 @@ pub fn generateLazySymbol(
|
|||||||
|
|
||||||
const comp = bin_file.comp;
|
const comp = bin_file.comp;
|
||||||
const zcu = comp.module.?;
|
const zcu = comp.module.?;
|
||||||
|
const ip = &zcu.intern_pool;
|
||||||
const target = comp.root_mod.resolved_target.result;
|
const target = comp.root_mod.resolved_target.result;
|
||||||
const endian = target.cpu.arch.endian();
|
const endian = target.cpu.arch.endian();
|
||||||
const gpa = comp.gpa;
|
const gpa = comp.gpa;
|
||||||
@ -151,8 +152,9 @@ pub fn generateLazySymbol(
|
|||||||
return Result.ok;
|
return Result.ok;
|
||||||
} else if (lazy_sym.ty.zigTypeTag(zcu) == .Enum) {
|
} else if (lazy_sym.ty.zigTypeTag(zcu) == .Enum) {
|
||||||
alignment.* = .@"1";
|
alignment.* = .@"1";
|
||||||
for (lazy_sym.ty.enumFields(zcu)) |tag_name_ip| {
|
const tag_names = lazy_sym.ty.enumFields(zcu);
|
||||||
const tag_name = zcu.intern_pool.stringToSlice(tag_name_ip);
|
for (0..tag_names.len) |tag_index| {
|
||||||
|
const tag_name = zcu.intern_pool.stringToSlice(tag_names.get(ip)[tag_index]);
|
||||||
try code.ensureUnusedCapacity(tag_name.len + 1);
|
try code.ensureUnusedCapacity(tag_name.len + 1);
|
||||||
code.appendSliceAssumeCapacity(tag_name);
|
code.appendSliceAssumeCapacity(tag_name);
|
||||||
code.appendAssumeCapacity(0);
|
code.appendAssumeCapacity(0);
|
||||||
|
|||||||
@ -2595,6 +2595,7 @@ pub fn genGlobalAsm(mod: *Module, writer: anytype) !void {
|
|||||||
|
|
||||||
pub fn genErrDecls(o: *Object) !void {
|
pub fn genErrDecls(o: *Object) !void {
|
||||||
const mod = o.dg.module;
|
const mod = o.dg.module;
|
||||||
|
const ip = &mod.intern_pool;
|
||||||
const writer = o.writer();
|
const writer = o.writer();
|
||||||
|
|
||||||
var max_name_len: usize = 0;
|
var max_name_len: usize = 0;
|
||||||
@ -2603,7 +2604,7 @@ pub fn genErrDecls(o: *Object) !void {
|
|||||||
try writer.writeAll("enum {\n");
|
try writer.writeAll("enum {\n");
|
||||||
o.indent_writer.pushIndent();
|
o.indent_writer.pushIndent();
|
||||||
for (mod.global_error_set.keys()[1..], 1..) |name_nts, value| {
|
for (mod.global_error_set.keys()[1..], 1..) |name_nts, value| {
|
||||||
const name = mod.intern_pool.stringToSlice(name_nts);
|
const name = ip.stringToSlice(name_nts);
|
||||||
max_name_len = @max(name.len, max_name_len);
|
max_name_len = @max(name.len, max_name_len);
|
||||||
const err_val = try mod.intern(.{ .err = .{
|
const err_val = try mod.intern(.{ .err = .{
|
||||||
.ty = .anyerror_type,
|
.ty = .anyerror_type,
|
||||||
@ -2621,8 +2622,8 @@ pub fn genErrDecls(o: *Object) !void {
|
|||||||
defer o.dg.gpa.free(name_buf);
|
defer o.dg.gpa.free(name_buf);
|
||||||
|
|
||||||
@memcpy(name_buf[0..name_prefix.len], name_prefix);
|
@memcpy(name_buf[0..name_prefix.len], name_prefix);
|
||||||
for (mod.global_error_set.keys()) |name_nts| {
|
for (mod.global_error_set.keys()) |name_ip| {
|
||||||
const name = mod.intern_pool.stringToSlice(name_nts);
|
const name = ip.stringToSlice(name_ip);
|
||||||
@memcpy(name_buf[name_prefix.len..][0..name.len], name);
|
@memcpy(name_buf[name_prefix.len..][0..name.len], name);
|
||||||
const identifier = name_buf[0 .. name_prefix.len + name.len];
|
const identifier = name_buf[0 .. name_prefix.len + name.len];
|
||||||
|
|
||||||
@ -2652,7 +2653,7 @@ pub fn genErrDecls(o: *Object) !void {
|
|||||||
try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, .none, .complete);
|
try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, .none, .complete);
|
||||||
try writer.writeAll(" = {");
|
try writer.writeAll(" = {");
|
||||||
for (mod.global_error_set.keys(), 0..) |name_nts, value| {
|
for (mod.global_error_set.keys(), 0..) |name_nts, value| {
|
||||||
const name = mod.intern_pool.stringToSlice(name_nts);
|
const name = ip.stringToSlice(name_nts);
|
||||||
if (value != 0) try writer.writeByte(',');
|
if (value != 0) try writer.writeByte(',');
|
||||||
|
|
||||||
const len_val = try mod.intValue(Type.usize, name.len);
|
const len_val = try mod.intValue(Type.usize, name.len);
|
||||||
@ -2730,6 +2731,7 @@ fn genExports(o: *Object) !void {
|
|||||||
|
|
||||||
pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
|
pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
|
||||||
const mod = o.dg.module;
|
const mod = o.dg.module;
|
||||||
|
const ip = &mod.intern_pool;
|
||||||
const w = o.writer();
|
const w = o.writer();
|
||||||
const key = lazy_fn.key_ptr.*;
|
const key = lazy_fn.key_ptr.*;
|
||||||
const val = lazy_fn.value_ptr;
|
const val = lazy_fn.value_ptr;
|
||||||
@ -2747,23 +2749,23 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void {
|
|||||||
try w.writeByte('(');
|
try w.writeByte('(');
|
||||||
try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
|
try o.dg.renderTypeAndName(w, enum_ty, .{ .identifier = "tag" }, Const, .none, .complete);
|
||||||
try w.writeAll(") {\n switch (tag) {\n");
|
try w.writeAll(") {\n switch (tag) {\n");
|
||||||
for (enum_ty.enumFields(mod), 0..) |name_ip, index_usize| {
|
const tag_names = enum_ty.enumFields(mod);
|
||||||
const index = @as(u32, @intCast(index_usize));
|
for (0..tag_names.len) |tag_index| {
|
||||||
const name = mod.intern_pool.stringToSlice(name_ip);
|
const tag_name = ip.stringToSlice(tag_names.get(ip)[tag_index]);
|
||||||
const tag_val = try mod.enumValueFieldIndex(enum_ty, index);
|
const tag_val = try mod.enumValueFieldIndex(enum_ty, @intCast(tag_index));
|
||||||
|
|
||||||
const int_val = try tag_val.intFromEnum(enum_ty, mod);
|
const int_val = try tag_val.intFromEnum(enum_ty, mod);
|
||||||
|
|
||||||
const name_ty = try mod.arrayType(.{
|
const name_ty = try mod.arrayType(.{
|
||||||
.len = name.len,
|
.len = tag_name.len,
|
||||||
.child = .u8_type,
|
.child = .u8_type,
|
||||||
.sentinel = .zero_u8,
|
.sentinel = .zero_u8,
|
||||||
});
|
});
|
||||||
const name_val = try mod.intern(.{ .aggregate = .{
|
const name_val = try mod.intern(.{ .aggregate = .{
|
||||||
.ty = name_ty.toIntern(),
|
.ty = name_ty.toIntern(),
|
||||||
.storage = .{ .bytes = name },
|
.storage = .{ .bytes = tag_name },
|
||||||
} });
|
} });
|
||||||
const len_val = try mod.intValue(Type.usize, name.len);
|
const len_val = try mod.intValue(Type.usize, tag_name.len);
|
||||||
|
|
||||||
try w.print(" case {}: {{\n static ", .{
|
try w.print(" case {}: {{\n static ", .{
|
||||||
try o.dg.fmtIntLiteral(enum_ty, int_val, .Other),
|
try o.dg.fmtIntLiteral(enum_ty, int_val, .Other),
|
||||||
|
|||||||
@ -9574,6 +9574,7 @@ pub const FuncGen = struct {
|
|||||||
fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value {
|
||||||
const o = self.dg.object;
|
const o = self.dg.object;
|
||||||
const mod = o.module;
|
const mod = o.module;
|
||||||
|
const ip = &mod.intern_pool;
|
||||||
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op;
|
||||||
const operand = try self.resolveInst(ty_op.operand);
|
const operand = try self.resolveInst(ty_op.operand);
|
||||||
const error_set_ty = ty_op.ty.toType();
|
const error_set_ty = ty_op.ty.toType();
|
||||||
@ -9585,8 +9586,8 @@ pub const FuncGen = struct {
|
|||||||
var wip_switch = try self.wip.@"switch"(operand, invalid_block, @intCast(names.len));
|
var wip_switch = try self.wip.@"switch"(operand, invalid_block, @intCast(names.len));
|
||||||
defer wip_switch.finish(&self.wip);
|
defer wip_switch.finish(&self.wip);
|
||||||
|
|
||||||
for (names) |name| {
|
for (0..names.len) |name_index| {
|
||||||
const err_int = mod.global_error_set.getIndex(name).?;
|
const err_int = mod.global_error_set.getIndex(names.get(ip)[name_index]).?;
|
||||||
const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
|
const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
|
||||||
try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
|
try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2828,7 +2828,7 @@ fn addDbgInfoErrorSet(
|
|||||||
target: std.Target,
|
target: std.Target,
|
||||||
dbg_info_buffer: *std.ArrayList(u8),
|
dbg_info_buffer: *std.ArrayList(u8),
|
||||||
) !void {
|
) !void {
|
||||||
return addDbgInfoErrorSetNames(mod, ty, ty.errorSetNames(mod), target, dbg_info_buffer);
|
return addDbgInfoErrorSetNames(mod, ty, ty.errorSetNames(mod).get(&mod.intern_pool), target, dbg_info_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addDbgInfoErrorSetNames(
|
fn addDbgInfoErrorSetNames(
|
||||||
|
|||||||
11
src/type.zig
11
src/type.zig
@ -2908,22 +2908,21 @@ pub const Type = struct {
|
|||||||
|
|
||||||
// Asserts that `ty` is an error set and not `anyerror`.
|
// Asserts that `ty` is an error set and not `anyerror`.
|
||||||
// Asserts that `ty` is resolved if it is an inferred error set.
|
// Asserts that `ty` is resolved if it is an inferred error set.
|
||||||
pub fn errorSetNames(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {
|
pub fn errorSetNames(ty: Type, mod: *Module) InternPool.NullTerminatedString.Slice {
|
||||||
const ip = &mod.intern_pool;
|
const ip = &mod.intern_pool;
|
||||||
return switch (ip.indexToKey(ty.toIntern())) {
|
return switch (ip.indexToKey(ty.toIntern())) {
|
||||||
.error_set_type => |x| x.names.get(ip),
|
.error_set_type => |x| x.names,
|
||||||
.inferred_error_set_type => |i| switch (ip.funcIesResolved(i).*) {
|
.inferred_error_set_type => |i| switch (ip.funcIesResolved(i).*) {
|
||||||
.none => unreachable, // unresolved inferred error set
|
.none => unreachable, // unresolved inferred error set
|
||||||
.anyerror_type => unreachable,
|
.anyerror_type => unreachable,
|
||||||
else => |t| ip.indexToKey(t).error_set_type.names.get(ip),
|
else => |t| ip.indexToKey(t).error_set_type.names,
|
||||||
},
|
},
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enumFields(ty: Type, mod: *Module) []const InternPool.NullTerminatedString {
|
pub fn enumFields(ty: Type, mod: *Module) InternPool.NullTerminatedString.Slice {
|
||||||
const ip = &mod.intern_pool;
|
return mod.intern_pool.indexToKey(ty.toIntern()).enum_type.names;
|
||||||
return ip.indexToKey(ty.toIntern()).enum_type.names.get(ip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enumFieldCount(ty: Type, mod: *Module) usize {
|
pub fn enumFieldCount(ty: Type, mod: *Module) usize {
|
||||||
|
|||||||
31
test/cbe.zig
31
test/cbe.zig
@ -219,23 +219,22 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void {
|
|||||||
, "");
|
, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/ziglang/zig/issues/18954
|
{
|
||||||
//{
|
var case = ctx.exeFromCompiledC("inferred local const and var", .{}, b);
|
||||||
// var case = ctx.exeFromCompiledC("inferred local const and var", .{}, b);
|
|
||||||
|
|
||||||
// case.addCompareOutput(
|
case.addCompareOutput(
|
||||||
// \\fn add(a: i32, b: i32) i32 {
|
\\fn add(a: i32, b: i32) i32 {
|
||||||
// \\ return a + b;
|
\\ return a + b;
|
||||||
// \\}
|
\\}
|
||||||
// \\
|
\\
|
||||||
// \\pub export fn main() c_int {
|
\\pub export fn main() c_int {
|
||||||
// \\ const x = add(1, 2);
|
\\ const x = add(1, 2);
|
||||||
// \\ var y = add(3, 0);
|
\\ var y = add(3, 0);
|
||||||
// \\ y -= x;
|
\\ y -= x;
|
||||||
// \\ return y;
|
\\ return y;
|
||||||
// \\}
|
\\}
|
||||||
// , "");
|
, "");
|
||||||
//}
|
}
|
||||||
{
|
{
|
||||||
var case = ctx.exeFromCompiledC("control flow", .{}, b);
|
var case = ctx.exeFromCompiledC("control flow", .{}, b);
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user