authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-06-28 01:34:46-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-06-28 01:34:46-04:00
log975a66080790956bb5591dc8aaef6e7725e72e56
tree53d36639292305eef06d624aa496f47d9687598a
parent1188415f4cb73440fde05047cd8e6b79a2255efa
parenta71d00a4d504edfdb09cd169d29ca1bbc0b909c4
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11945 from ziglang/stage2-std

stage2 fixes towards standard library tests passing

13 files changed, 116 insertions(+), 31 deletions(-)

lib/std/crypto/25519/field.zig+7-8
......@@ -341,7 +341,7 @@ pub const Fe = struct {
341341 }
342342
343343 /// Square a field element `n` times
344 inline fn sqn(a: Fe, comptime n: comptime_int) Fe {
344 fn sqn(a: Fe, n: usize) Fe {
345345 var i: usize = 0;
346346 var fe = a;
347347 while (i < n) : (i += 1) {
......@@ -390,13 +390,12 @@ pub const Fe = struct {
390390 const _11 = a.mul(a.sq());
391391 const _1111 = _11.mul(_11.sq().sq());
392392 const _11111111 = _1111.mul(_1111.sq().sq().sq().sq());
393 var t = _11111111.sqn(2).mul(_11);
394 const u = t;
395 t = t.sqn(10).mul(u).sqn(10).mul(u);
396 t = t.sqn(30).mul(t);
397 t = t.sqn(60).mul(t);
398 t = t.sqn(120).mul(t).sqn(10).mul(u).sqn(3).mul(_11).sq();
399 return @bitCast(bool, @truncate(u1, ~(t.toBytes()[1] & 1)));
393 const u = _11111111.sqn(2).mul(_11);
394 const t = u.sqn(10).mul(u).sqn(10).mul(u);
395 const t2 = t.sqn(30).mul(t);
396 const t3 = t2.sqn(60).mul(t2);
397 const t4 = t3.sqn(120).mul(t3).sqn(10).mul(u).sqn(3).mul(_11).sq();
398 return @bitCast(bool, @truncate(u1, ~(t4.toBytes()[1] & 1)));
400399 }
401400
402401 fn uncheckedSqrt(x2: Fe) Fe {
lib/std/os/linux/arm64.zig+6-1
......@@ -98,8 +98,13 @@ pub fn syscall6(
9898 );
9999}
100100
101const CloneFn = switch (@import("builtin").zig_backend) {
102 .stage1 => fn (arg: usize) callconv(.C) u8,
103 else => *const fn (arg: usize) callconv(.C) u8,
104};
105
101106/// This matches the libc clone function.
102pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
107pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
103108
104109pub const restore = restore_rt;
105110
lib/std/os/linux/i386.zig+6-1
......@@ -118,8 +118,13 @@ pub fn socketcall(call: usize, args: [*]usize) usize {
118118 );
119119}
120120
121const CloneFn = switch (@import("builtin").zig_backend) {
122 .stage1 => fn (arg: usize) callconv(.C) u8,
123 else => *const fn (arg: usize) callconv(.C) u8,
124};
125
121126/// This matches the libc clone function.
122pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
127pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
123128
124129pub fn restore() callconv(.Naked) void {
125130 return asm volatile ("int $0x80"
lib/std/os/linux/mips.zig+6-1
......@@ -190,8 +190,13 @@ pub fn syscall7(
190190 );
191191}
192192
193const CloneFn = switch (@import("builtin").zig_backend) {
194 .stage1 => fn (arg: usize) callconv(.C) u8,
195 else => *const fn (arg: usize) callconv(.C) u8,
196};
197
193198/// This matches the libc clone function.
194pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
199pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
195200
196201pub fn restore() callconv(.Naked) void {
197202 return asm volatile ("syscall"
lib/std/os/linux/powerpc.zig+6-1
......@@ -126,8 +126,13 @@ pub fn syscall6(
126126 );
127127}
128128
129const CloneFn = switch (@import("builtin").zig_backend) {
130 .stage1 => fn (arg: usize) callconv(.C) u8,
131 else => *const fn (arg: usize) callconv(.C) u8,
132};
133
129134/// This matches the libc clone function.
130pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
135pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
131136
132137pub const restore = restore_rt;
133138
lib/std/os/linux/powerpc64.zig+6-1
......@@ -126,8 +126,13 @@ pub fn syscall6(
126126 );
127127}
128128
129const CloneFn = switch (@import("builtin").zig_backend) {
130 .stage1 => fn (arg: usize) callconv(.C) u8,
131 else => *const fn (arg: usize) callconv(.C) u8,
132};
133
129134/// This matches the libc clone function.
130pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
135pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
131136
132137pub const restore = restore_rt;
133138
lib/std/os/linux/riscv64.zig+6-1
......@@ -95,7 +95,12 @@ pub fn syscall6(
9595 );
9696}
9797
98pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
98const CloneFn = switch (@import("builtin").zig_backend) {
99 .stage1 => fn (arg: usize) callconv(.C) u8,
100 else => *const fn (arg: usize) callconv(.C) u8,
101};
102
103pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
99104
100105pub const restore = restore_rt;
101106
lib/std/os/linux/sparc64.zig+6-1
......@@ -178,8 +178,13 @@ pub fn syscall6(
178178 );
179179}
180180
181const CloneFn = switch (@import("builtin").zig_backend) {
182 .stage1 => fn (arg: usize) callconv(.C) u8,
183 else => *const fn (arg: usize) callconv(.C) u8,
184};
185
181186/// This matches the libc clone function.
182pub extern fn clone(func: fn (arg: usize) callconv(.C) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
187pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
183188
184189pub const restore = restore_rt;
185190
lib/std/x/os/net.zig+16-1
......@@ -9,10 +9,25 @@ const testing = std.testing;
99const native_os = builtin.os;
1010const have_ifnamesize = @hasDecl(os.system, "IFNAMESIZE");
1111
12pub const ResolveScopeIdError = error{
13 NameTooLong,
14 PermissionDenied,
15 AddressFamilyNotSupported,
16 ProtocolFamilyNotAvailable,
17 ProcessFdQuotaExceeded,
18 SystemFdQuotaExceeded,
19 SystemResources,
20 ProtocolNotSupported,
21 SocketTypeNotSupported,
22 InterfaceNotFound,
23 FileSystem,
24 Unexpected,
25};
26
1227/// Resolves a network interface name into a scope/zone ID. It returns
1328/// an error if either resolution fails, or if the interface name is
1429/// too long.
15pub fn resolveScopeId(name: []const u8) !u32 {
30pub fn resolveScopeId(name: []const u8) ResolveScopeIdError!u32 {
1631 if (have_ifnamesize) {
1732 if (name.len >= os.IFNAMESIZE) return error.NameTooLong;
1833
src/Module.zig+13-8
......@@ -4607,6 +4607,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
46074607 DeclAdapter{ .mod = mod },
46084608 Namespace.DeclContext{ .module = mod },
46094609 );
4610 const comp = mod.comp;
46104611 if (!gop.found_existing) {
46114612 const new_decl_index = try mod.allocateNewDecl(namespace, decl_node, iter.parent_decl.src_scope);
46124613 const new_decl = mod.declPtr(new_decl_index);
......@@ -4625,7 +4626,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
46254626 1 => blk: {
46264627 // test decl with no name. Skip the part where we check against
46274628 // the test name filter.
4628 if (!mod.comp.bin_file.options.is_test) break :blk false;
4629 if (!comp.bin_file.options.is_test) break :blk false;
46294630 if (decl_pkg != mod.main_pkg) {
46304631 if (!mod.main_pkg_in_std) break :blk false;
46314632 const std_pkg = mod.main_pkg.table.get("std").?;
......@@ -4636,19 +4637,23 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
46364637 },
46374638 else => blk: {
46384639 if (!is_named_test) break :blk false;
4639 if (!mod.comp.bin_file.options.is_test) break :blk false;
4640 if (!comp.bin_file.options.is_test) break :blk false;
46404641 if (decl_pkg != mod.main_pkg) {
46414642 if (!mod.main_pkg_in_std) break :blk false;
46424643 const std_pkg = mod.main_pkg.table.get("std").?;
46434644 if (std_pkg != decl_pkg) break :blk false;
46444645 }
4645 // TODO check the name against --test-filter
4646 if (comp.test_filter) |test_filter| {
4647 if (mem.indexOf(u8, decl_name, test_filter) == null) {
4648 break :blk false;
4649 }
4650 }
46464651 try mod.test_functions.put(gpa, new_decl_index, {});
46474652 break :blk true;
46484653 },
46494654 };
46504655 if (want_analysis) {
4651 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index });
4656 comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index });
46524657 }
46534658 new_decl.is_pub = is_pub;
46544659 new_decl.is_exported = is_exported;
......@@ -4675,24 +4680,24 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
46754680 decl.has_linksection_or_addrspace = has_linksection_or_addrspace;
46764681 decl.zir_decl_index = @intCast(u32, decl_sub_index);
46774682 if (decl.getFunction()) |_| {
4678 switch (mod.comp.bin_file.tag) {
4683 switch (comp.bin_file.tag) {
46794684 .coff => {
46804685 // TODO Implement for COFF
46814686 },
46824687 .elf => if (decl.fn_link.elf.len != 0) {
46834688 // TODO Look into detecting when this would be unnecessary by storing enough state
46844689 // in `Decl` to notice that the line number did not change.
4685 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
4690 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
46864691 },
46874692 .macho => if (decl.fn_link.macho.len != 0) {
46884693 // TODO Look into detecting when this would be unnecessary by storing enough state
46894694 // in `Decl` to notice that the line number did not change.
4690 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
4695 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
46914696 },
46924697 .plan9 => {
46934698 // TODO Look into detecting when this would be unnecessary by storing enough state
46944699 // in `Decl` to notice that the line number did not change.
4695 mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
4700 comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl_index });
46964701 },
46974702 .c, .wasm, .spirv, .nvptx => {},
46984703 }
src/codegen/llvm.zig+28-5
......@@ -4197,7 +4197,7 @@ pub const FuncGen = struct {
41974197 }
41984198
41994199 var it = iterateParamTypes(self.dg, fn_info);
4200 while (it.next()) |lowering| switch (lowering) {
4200 while (it.nextCall(self, args)) |lowering| switch (lowering) {
42014201 .no_bits => continue,
42024202 .byval => {
42034203 const arg = args[it.zig_index - 1];
......@@ -7212,11 +7212,17 @@ pub const FuncGen = struct {
72127212 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
72137213 if (self.liveness.isUnused(inst)) return null;
72147214
7215 const llvm_usize = try self.dg.lowerType(Type.usize);
7216 const target = self.dg.module.getTarget();
7217 if (!target_util.supportsReturnAddress(target)) {
7218 // https://github.com/ziglang/zig/issues/11946
7219 return llvm_usize.constNull();
7220 }
7221
72157222 const llvm_i32 = self.context.intType(32);
72167223 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
72177224 const params = [_]*const llvm.Value{llvm_i32.constNull()};
72187225 const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
7219 const llvm_usize = try self.dg.lowerType(Type.usize);
72207226 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
72217227 }
72227228
......@@ -8021,7 +8027,6 @@ pub const FuncGen = struct {
80218027 assert(union_obj.haveFieldTypes());
80228028 const field = union_obj.fields.values()[extra.field_index];
80238029 const field_llvm_ty = try self.dg.lowerType(field.ty);
8024 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
80258030 const field_size = field.ty.abiSize(target);
80268031 const field_align = field.normalAlignment(target);
80278032
......@@ -8044,6 +8049,7 @@ pub const FuncGen = struct {
80448049 const fields: [1]*const llvm.Type = .{payload};
80458050 break :t self.context.structType(&fields, fields.len, .False);
80468051 }
8052 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
80478053 var fields: [3]*const llvm.Type = undefined;
80488054 var fields_len: c_uint = 2;
80498055 if (layout.tag_align >= layout.payload_align) {
......@@ -8100,6 +8106,7 @@ pub const FuncGen = struct {
81008106 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
81018107 };
81028108 const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, indices.len, "");
8109 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
81038110 const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False);
81048111 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
81058112 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(target));
......@@ -9004,10 +9011,26 @@ const ParamTypeIterator = struct {
90049011 slice,
90059012 };
90069013
9007 fn next(it: *ParamTypeIterator) ?Lowering {
9014 pub fn next(it: *ParamTypeIterator) ?Lowering {
90089015 if (it.zig_index >= it.fn_info.param_types.len) return null;
9009
90109016 const ty = it.fn_info.param_types[it.zig_index];
9017 return nextInner(it, ty);
9018 }
9019
9020 /// `airCall` uses this instead of `next` so that it can take into account variadic functions.
9021 pub fn nextCall(it: *ParamTypeIterator, fg: *FuncGen, args: []const Air.Inst.Ref) ?Lowering {
9022 if (it.zig_index >= it.fn_info.param_types.len) {
9023 if (it.zig_index >= args.len) {
9024 return null;
9025 } else {
9026 return nextInner(it, fg.air.typeOf(args[it.zig_index]));
9027 }
9028 } else {
9029 return nextInner(it, it.fn_info.param_types[it.zig_index]);
9030 }
9031 }
9032
9033 fn nextInner(it: *ParamTypeIterator, ty: Type) ?Lowering {
90119034 if (!ty.hasRuntimeBitsIgnoreComptime()) {
90129035 it.zig_index += 1;
90139036 return .no_bits;
src/stage1/codegen.cpp+2-2
......@@ -6764,8 +6764,8 @@ static LLVMValueRef ir_render_return_address(CodeGen *g, Stage1Air *executable,
67646764 Stage1AirInstReturnAddress *instruction)
67656765{
67666766 if ((target_is_wasm(g->zig_target) && g->zig_target->os != OsEmscripten) || target_is_bpf(g->zig_target)) {
6767 // I got this error from LLVM 10:
6768 // "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address"
6767 // LLVM 13 reports "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address"
6768 // https://github.com/ziglang/zig/issues/11946
67696769 return LLVMConstNull(get_llvm_type(g, instruction->base.value->type));
67706770 }
67716771
src/target.zig+8
......@@ -283,6 +283,14 @@ pub fn supportsStackProbing(target: std.Target) bool {
283283 (target.cpu.arch == .i386 or target.cpu.arch == .x86_64);
284284}
285285
286pub fn supportsReturnAddress(target: std.Target) bool {
287 return switch (target.cpu.arch) {
288 .wasm32, .wasm64 => target.os.tag == .emscripten,
289 .bpfel, .bpfeb => false,
290 else => true,
291 };
292}
293
286294pub fn osToLLVM(os_tag: std.Target.Os.Tag) llvm.OSType {
287295 return switch (os_tag) {
288296 .freestanding, .other, .opencl, .glsl450, .vulkan, .plan9 => .UnknownOS,