@@ -2063,7 +2063,8 @@ pub const Const = struct {
|
||||
// This is the inverse of calcDivLimbsBufferLen
|
||||
const available_len = (limbs.len / 3) - 2;
|
||||
|
||||
const biggest: Const = .{
|
||||
// TODO https://github.com/ziglang/zig/issues/11439
|
||||
const biggest = comptime Const{
|
||||
.limbs = &([1]Limb{math.maxInt(Limb)} ** available_len),
|
||||
.positive = false,
|
||||
};
|
||||
|
||||
@@ -100,7 +100,12 @@ pub fn syscall6(
|
||||
}
|
||||
|
||||
/// This matches the libc clone function.
|
||||
pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
|
||||
pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
|
||||
|
||||
const CloneFn = switch (@import("builtin").zig_backend) {
|
||||
.stage1 => fn (arg: usize) callconv(.C) u8,
|
||||
else => *const fn (arg: usize) callconv(.C) u8,
|
||||
};
|
||||
|
||||
pub const restore = restore_rt;
|
||||
|
||||
|
||||
@@ -2851,6 +2851,9 @@ fn varDecl(
|
||||
return &sub_scope.base;
|
||||
},
|
||||
.keyword_var => {
|
||||
const old_rl_ty_inst = gz.rl_ty_inst;
|
||||
defer gz.rl_ty_inst = old_rl_ty_inst;
|
||||
|
||||
const is_comptime = var_decl.comptime_token != null or gz.force_comptime;
|
||||
var resolve_inferred_alloc: Zir.Inst.Ref = .none;
|
||||
const var_data: struct {
|
||||
@@ -2875,6 +2878,7 @@ fn varDecl(
|
||||
});
|
||||
}
|
||||
};
|
||||
gz.rl_ty_inst = type_inst;
|
||||
break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };
|
||||
} else a: {
|
||||
const alloc = alloc: {
|
||||
@@ -2894,6 +2898,7 @@ fn varDecl(
|
||||
});
|
||||
}
|
||||
};
|
||||
gz.rl_ty_inst = .none;
|
||||
resolve_inferred_alloc = alloc;
|
||||
break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } };
|
||||
};
|
||||
|
||||
49
src/Sema.zig
49
src/Sema.zig
@@ -12432,7 +12432,8 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const src: LazySrcLoc = .unneeded;
|
||||
// TODO better source location
|
||||
const src: LazySrcLoc = sema.src;
|
||||
const elem_ty_src: LazySrcLoc = .unneeded;
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].ptr_type;
|
||||
const extra = sema.code.extraData(Zir.Inst.PtrType, inst_data.payload_index);
|
||||
@@ -13086,22 +13087,38 @@ fn fieldType(
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const resolved_ty = try sema.resolveTypeFields(block, ty_src, aggregate_ty);
|
||||
const target = sema.mod.getTarget();
|
||||
switch (resolved_ty.zigTypeTag()) {
|
||||
.Struct => {
|
||||
const struct_obj = resolved_ty.castTag(.@"struct").?.data;
|
||||
const field = struct_obj.fields.get(field_name) orelse
|
||||
return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name);
|
||||
return sema.addType(field.ty);
|
||||
},
|
||||
.Union => {
|
||||
const union_obj = resolved_ty.cast(Type.Payload.Union).?.data;
|
||||
const field = union_obj.fields.get(field_name) orelse
|
||||
return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
|
||||
return sema.addType(field.ty);
|
||||
},
|
||||
else => return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
|
||||
var cur_ty = resolved_ty;
|
||||
while (true) {
|
||||
switch (cur_ty.zigTypeTag()) {
|
||||
.Struct => {
|
||||
const struct_obj = cur_ty.castTag(.@"struct").?.data;
|
||||
const field = struct_obj.fields.get(field_name) orelse
|
||||
return sema.failWithBadStructFieldAccess(block, struct_obj, field_src, field_name);
|
||||
return sema.addType(field.ty);
|
||||
},
|
||||
.Union => {
|
||||
const union_obj = cur_ty.cast(Type.Payload.Union).?.data;
|
||||
const field = union_obj.fields.get(field_name) orelse
|
||||
return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
|
||||
return sema.addType(field.ty);
|
||||
},
|
||||
.Optional => {
|
||||
if (cur_ty.castTag(.optional)) |some| {
|
||||
// Struct/array init through optional requires the child type to not be a pointer.
|
||||
// If the child of .optional is a pointer it'll error on the next loop.
|
||||
cur_ty = some.data;
|
||||
continue;
|
||||
}
|
||||
},
|
||||
.ErrorUnion => {
|
||||
cur_ty = cur_ty.errorUnionPayload();
|
||||
continue;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return sema.fail(block, ty_src, "expected struct or union; found '{}'", .{
|
||||
resolved_ty.fmt(target),
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -624,9 +624,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const is_volatile = (extra.data.flags & 0x80000000) != 0;
|
||||
const clobbers_len = @truncate(u31, extra.data.flags);
|
||||
var extra_i: usize = extra.end;
|
||||
const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i .. extra_i + extra.data.outputs_len]);
|
||||
const outputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i .. extra_i + extra.data.outputs_len]);
|
||||
extra_i += outputs.len;
|
||||
const inputs = @bitCast([]const Air.Inst.Ref, self.air.extra[extra_i .. extra_i + extra.data.inputs_len]);
|
||||
const inputs = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra_i .. extra_i + extra.data.inputs_len]);
|
||||
extra_i += inputs.len;
|
||||
|
||||
const dead = !is_volatile and self.liveness.isUnused(inst);
|
||||
@@ -826,7 +826,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallOptions.
|
||||
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
|
||||
const callee = pl_op.operand;
|
||||
const extra = self.air.extraData(Air.Call, pl_op.payload);
|
||||
const args = @bitCast([]const Air.Inst.Ref, self.air.extra[extra.end .. extra.end + extra.data.args_len]);
|
||||
const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end .. extra.end + extra.data.args_len]);
|
||||
const ty = self.air.typeOf(callee);
|
||||
const fn_ty = switch (ty.zigTypeTag()) {
|
||||
.Fn => ty,
|
||||
|
||||
@@ -4637,6 +4637,7 @@ pub const FuncGen = struct {
|
||||
switch (state) {
|
||||
.start => switch (byte) {
|
||||
'%' => state = .percent,
|
||||
'$' => try rendered_template.appendSlice("$$"),
|
||||
else => try rendered_template.append(byte),
|
||||
},
|
||||
.percent => switch (byte) {
|
||||
|
||||
@@ -1317,6 +1317,9 @@ pub fn parseDylib(self: *MachO, path: []const u8, opts: DylibCreateOpts) ParseDy
|
||||
error.EndOfStream, error.NotDylib => {
|
||||
try file.seekTo(0);
|
||||
|
||||
// TODO https://github.com/ziglang/zig/issues/11367
|
||||
if (@import("builtin").zig_backend != .stage1) return error.Unexpected;
|
||||
|
||||
var lib_stub = LibStub.loadFromFile(self.base.allocator, file) catch {
|
||||
dylib.deinit(self.base.allocator);
|
||||
return false;
|
||||
@@ -5747,7 +5750,6 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, buffer: []const u8) !void {
|
||||
while (true) {
|
||||
const inst = reader.readByte() catch |err| switch (err) {
|
||||
error.EndOfStream => break,
|
||||
else => return err,
|
||||
};
|
||||
const opcode: u8 = inst & macho.BIND_OPCODE_MASK;
|
||||
|
||||
@@ -5875,7 +5877,7 @@ fn writeFunctionStarts(self: *MachO) !void {
|
||||
mem.set(u8, buffer, 0);
|
||||
|
||||
var stream = std.io.fixedBufferStream(buffer);
|
||||
var writer = stream.writer();
|
||||
const writer = stream.writer();
|
||||
|
||||
for (offsets.items) |offset| {
|
||||
try std.leb.writeULEB128(writer, offset);
|
||||
@@ -6236,7 +6238,8 @@ fn writeLoadCommands(self: *MachO) !void {
|
||||
|
||||
var buffer = try self.base.allocator.alloc(u8, sizeofcmds);
|
||||
defer self.base.allocator.free(buffer);
|
||||
var writer = std.io.fixedBufferStream(buffer).writer();
|
||||
var fib = std.io.fixedBufferStream(buffer);
|
||||
const writer = fib.writer();
|
||||
for (self.load_commands.items) |lc| {
|
||||
try lc.write(writer);
|
||||
}
|
||||
@@ -6416,7 +6419,7 @@ fn snapshotState(self: *MachO) !void {
|
||||
error.Unseekable => try out_file.writer().writeByte('['),
|
||||
else => |e| return e,
|
||||
}
|
||||
var writer = out_file.writer();
|
||||
const writer = out_file.writer();
|
||||
|
||||
var snapshot = Snapshot{
|
||||
.timestamp = std.time.nanoTimestamp(),
|
||||
|
||||
@@ -171,7 +171,6 @@ fn parseTableOfContents(self: *Archive, allocator: Allocator, reader: anytype) !
|
||||
while (true) {
|
||||
const n_strx = symtab_reader.readIntLittle(u32) catch |err| switch (err) {
|
||||
error.EndOfStream => break,
|
||||
else => |e| return e,
|
||||
};
|
||||
const object_offset = try symtab_reader.readIntLittle(u32);
|
||||
|
||||
|
||||
@@ -472,7 +472,8 @@ fn writeLoadCommands(self: *DebugSymbols, allocator: Allocator) !void {
|
||||
|
||||
var buffer = try allocator.alloc(u8, sizeofcmds);
|
||||
defer allocator.free(buffer);
|
||||
var writer = std.io.fixedBufferStream(buffer).writer();
|
||||
var fib = std.io.fixedBufferStream(buffer);
|
||||
const writer = fib.writer();
|
||||
for (self.load_commands.items) |lc| {
|
||||
try lc.write(writer);
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ pub const Id = struct {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deinit(id: *Id, allocator: Allocator) void {
|
||||
pub fn deinit(id: Id, allocator: Allocator) void {
|
||||
allocator.free(id.name);
|
||||
}
|
||||
|
||||
|
||||
@@ -492,7 +492,8 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) !
|
||||
mem.copy(u8, atom.code.items, code);
|
||||
}
|
||||
|
||||
try atom.parseRelocs(relocs, .{
|
||||
// TODO stage2 bug: @alignCast shouldn't be needed
|
||||
try atom.parseRelocs(@alignCast(@alignOf(macho.relocation_info), relocs), .{
|
||||
.base_addr = sect.addr,
|
||||
.allocator = allocator,
|
||||
.object = self,
|
||||
|
||||
@@ -312,7 +312,8 @@ fn Parser(comptime ReaderType: type) type {
|
||||
var section_index: u32 = 0;
|
||||
while (self.reader.reader().readByte()) |byte| : (section_index += 1) {
|
||||
const len = try readLeb(u32, self.reader.reader());
|
||||
const reader = std.io.limitedReader(self.reader.reader(), len).reader();
|
||||
var limited_reader = std.io.limitedReader(self.reader.reader(), len);
|
||||
const reader = limited_reader.reader();
|
||||
switch (@intToEnum(std.wasm.Section, byte)) {
|
||||
.custom => {
|
||||
const name_len = try readLeb(u32, reader);
|
||||
|
||||
@@ -859,7 +859,6 @@ test "catch in block has correct result location" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn open() error{A}!@This() {
|
||||
@@ -887,3 +886,22 @@ test "labeled block with runtime branch forwards its result location type to bre
|
||||
};
|
||||
try expect(e == .b);
|
||||
}
|
||||
|
||||
test "try in labeled block doesn't cast to wrong type" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
a: u32,
|
||||
fn foo() anyerror!u32 {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
const s: ?*S = blk: {
|
||||
var a = try S.foo();
|
||||
|
||||
_ = a;
|
||||
break :blk null;
|
||||
};
|
||||
_ = s;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user