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 {...@@ -341,7 +341,7 @@ pub const Fe = struct {
341 }341 }
342342
343 /// Square a field element `n` times343 /// 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 {
345 var i: usize = 0;345 var i: usize = 0;
346 var fe = a;346 var fe = a;
347 while (i < n) : (i += 1) {347 while (i < n) : (i += 1) {
...@@ -390,13 +390,12 @@ pub const Fe = struct {...@@ -390,13 +390,12 @@ pub const Fe = struct {
390 const _11 = a.mul(a.sq());390 const _11 = a.mul(a.sq());
391 const _1111 = _11.mul(_11.sq().sq());391 const _1111 = _11.mul(_11.sq().sq());
392 const _11111111 = _1111.mul(_1111.sq().sq().sq().sq());392 const _11111111 = _1111.mul(_1111.sq().sq().sq().sq());
393 var t = _11111111.sqn(2).mul(_11);393 const u = _11111111.sqn(2).mul(_11);
394 const u = t;394 const t = u.sqn(10).mul(u).sqn(10).mul(u);
395 t = t.sqn(10).mul(u).sqn(10).mul(u);395 const t2 = t.sqn(30).mul(t);
396 t = t.sqn(30).mul(t);396 const t3 = t2.sqn(60).mul(t2);
397 t = t.sqn(60).mul(t);397 const t4 = t3.sqn(120).mul(t3).sqn(10).mul(u).sqn(3).mul(_11).sq();
398 t = t.sqn(120).mul(t).sqn(10).mul(u).sqn(3).mul(_11).sq();398 return @bitCast(bool, @truncate(u1, ~(t4.toBytes()[1] & 1)));
399 return @bitCast(bool, @truncate(u1, ~(t.toBytes()[1] & 1)));
400 }399 }
401400
402 fn uncheckedSqrt(x2: Fe) Fe {401 fn uncheckedSqrt(x2: Fe) Fe {
lib/std/os/linux/arm64.zig+6-1
...@@ -98,8 +98,13 @@ pub fn syscall6(...@@ -98,8 +98,13 @@ pub fn syscall6(
98 );98 );
99}99}
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
101/// This matches the libc clone function.106/// 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
104pub const restore = restore_rt;109pub 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 {...@@ -118,8 +118,13 @@ pub fn socketcall(call: usize, args: [*]usize) usize {
118 );118 );
119}119}
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
121/// This matches the libc clone function.126/// 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
124pub fn restore() callconv(.Naked) void {129pub fn restore() callconv(.Naked) void {
125 return asm volatile ("int $0x80"130 return asm volatile ("int $0x80"
lib/std/os/linux/mips.zig+6-1
...@@ -190,8 +190,13 @@ pub fn syscall7(...@@ -190,8 +190,13 @@ pub fn syscall7(
190 );190 );
191}191}
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
193/// This matches the libc clone function.198/// 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
196pub fn restore() callconv(.Naked) void {201pub fn restore() callconv(.Naked) void {
197 return asm volatile ("syscall"202 return asm volatile ("syscall"
lib/std/os/linux/powerpc.zig+6-1
...@@ -126,8 +126,13 @@ pub fn syscall6(...@@ -126,8 +126,13 @@ pub fn syscall6(
126 );126 );
127}127}
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
129/// This matches the libc clone function.134/// 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
132pub const restore = restore_rt;137pub const restore = restore_rt;
133138
lib/std/os/linux/powerpc64.zig+6-1
...@@ -126,8 +126,13 @@ pub fn syscall6(...@@ -126,8 +126,13 @@ pub fn syscall6(
126 );126 );
127}127}
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
129/// This matches the libc clone function.134/// 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
132pub const restore = restore_rt;137pub const restore = restore_rt;
133138
lib/std/os/linux/riscv64.zig+6-1
...@@ -95,7 +95,12 @@ pub fn syscall6(...@@ -95,7 +95,12 @@ pub fn syscall6(
95 );95 );
96}96}
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
100pub const restore = restore_rt;105pub const restore = restore_rt;
101106
lib/std/os/linux/sparc64.zig+6-1
...@@ -178,8 +178,13 @@ pub fn syscall6(...@@ -178,8 +178,13 @@ pub fn syscall6(
178 );178 );
179}179}
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
181/// This matches the libc clone function.186/// 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
184pub const restore = restore_rt;189pub const restore = restore_rt;
185190
lib/std/x/os/net.zig+16-1
...@@ -9,10 +9,25 @@ const testing = std.testing;...@@ -9,10 +9,25 @@ const testing = std.testing;
9const native_os = builtin.os;9const native_os = builtin.os;
10const have_ifnamesize = @hasDecl(os.system, "IFNAMESIZE");10const 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
12/// Resolves a network interface name into a scope/zone ID. It returns27/// Resolves a network interface name into a scope/zone ID. It returns
13/// an error if either resolution fails, or if the interface name is28/// an error if either resolution fails, or if the interface name is
14/// too long.29/// too long.
15pub fn resolveScopeId(name: []const u8) !u32 {30pub fn resolveScopeId(name: []const u8) ResolveScopeIdError!u32 {
16 if (have_ifnamesize) {31 if (have_ifnamesize) {
17 if (name.len >= os.IFNAMESIZE) return error.NameTooLong;32 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...@@ -4607,6 +4607,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4607 DeclAdapter{ .mod = mod },4607 DeclAdapter{ .mod = mod },
4608 Namespace.DeclContext{ .module = mod },4608 Namespace.DeclContext{ .module = mod },
4609 );4609 );
4610 const comp = mod.comp;
4610 if (!gop.found_existing) {4611 if (!gop.found_existing) {
4611 const new_decl_index = try mod.allocateNewDecl(namespace, decl_node, iter.parent_decl.src_scope);4612 const new_decl_index = try mod.allocateNewDecl(namespace, decl_node, iter.parent_decl.src_scope);
4612 const new_decl = mod.declPtr(new_decl_index);4613 const new_decl = mod.declPtr(new_decl_index);
...@@ -4625,7 +4626,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4625,7 +4626,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4625 1 => blk: {4626 1 => blk: {
4626 // test decl with no name. Skip the part where we check against4627 // test decl with no name. Skip the part where we check against
4627 // the test name filter.4628 // 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;
4629 if (decl_pkg != mod.main_pkg) {4630 if (decl_pkg != mod.main_pkg) {
4630 if (!mod.main_pkg_in_std) break :blk false;4631 if (!mod.main_pkg_in_std) break :blk false;
4631 const std_pkg = mod.main_pkg.table.get("std").?;4632 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...@@ -4636,19 +4637,23 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4636 },4637 },
4637 else => blk: {4638 else => blk: {
4638 if (!is_named_test) break :blk false;4639 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;
4640 if (decl_pkg != mod.main_pkg) {4641 if (decl_pkg != mod.main_pkg) {
4641 if (!mod.main_pkg_in_std) break :blk false;4642 if (!mod.main_pkg_in_std) break :blk false;
4642 const std_pkg = mod.main_pkg.table.get("std").?;4643 const std_pkg = mod.main_pkg.table.get("std").?;
4643 if (std_pkg != decl_pkg) break :blk false;4644 if (std_pkg != decl_pkg) break :blk false;
4644 }4645 }
4645 // TODO check the name against --test-filter4646 if (comp.test_filter) |test_filter| {
4647 if (mem.indexOf(u8, decl_name, test_filter) == null) {
4648 break :blk false;
4649 }
4650 }
4646 try mod.test_functions.put(gpa, new_decl_index, {});4651 try mod.test_functions.put(gpa, new_decl_index, {});
4647 break :blk true;4652 break :blk true;
4648 },4653 },
4649 };4654 };
4650 if (want_analysis) {4655 if (want_analysis) {
4651 mod.comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index });4656 comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index });
4652 }4657 }
4653 new_decl.is_pub = is_pub;4658 new_decl.is_pub = is_pub;
4654 new_decl.is_exported = is_exported;4659 new_decl.is_exported = is_exported;
...@@ -4675,24 +4680,24 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -4675,24 +4680,24 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
4675 decl.has_linksection_or_addrspace = has_linksection_or_addrspace;4680 decl.has_linksection_or_addrspace = has_linksection_or_addrspace;
4676 decl.zir_decl_index = @intCast(u32, decl_sub_index);4681 decl.zir_decl_index = @intCast(u32, decl_sub_index);
4677 if (decl.getFunction()) |_| {4682 if (decl.getFunction()) |_| {
4678 switch (mod.comp.bin_file.tag) {4683 switch (comp.bin_file.tag) {
4679 .coff => {4684 .coff => {
4680 // TODO Implement for COFF4685 // TODO Implement for COFF
4681 },4686 },
4682 .elf => if (decl.fn_link.elf.len != 0) {4687 .elf => if (decl.fn_link.elf.len != 0) {
4683 // TODO Look into detecting when this would be unnecessary by storing enough state4688 // TODO Look into detecting when this would be unnecessary by storing enough state
4684 // in `Decl` to notice that the line number did not change.4689 // 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 });
4686 },4691 },
4687 .macho => if (decl.fn_link.macho.len != 0) {4692 .macho => if (decl.fn_link.macho.len != 0) {
4688 // TODO Look into detecting when this would be unnecessary by storing enough state4693 // TODO Look into detecting when this would be unnecessary by storing enough state
4689 // in `Decl` to notice that the line number did not change.4694 // 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 });
4691 },4696 },
4692 .plan9 => {4697 .plan9 => {
4693 // TODO Look into detecting when this would be unnecessary by storing enough state4698 // TODO Look into detecting when this would be unnecessary by storing enough state
4694 // in `Decl` to notice that the line number did not change.4699 // 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 });
4696 },4701 },
4697 .c, .wasm, .spirv, .nvptx => {},4702 .c, .wasm, .spirv, .nvptx => {},
4698 }4703 }
src/codegen/llvm.zig+28-5
...@@ -4197,7 +4197,7 @@ pub const FuncGen = struct {...@@ -4197,7 +4197,7 @@ pub const FuncGen = struct {
4197 }4197 }
41984198
4199 var it = iterateParamTypes(self.dg, fn_info);4199 var it = iterateParamTypes(self.dg, fn_info);
4200 while (it.next()) |lowering| switch (lowering) {4200 while (it.nextCall(self, args)) |lowering| switch (lowering) {
4201 .no_bits => continue,4201 .no_bits => continue,
4202 .byval => {4202 .byval => {
4203 const arg = args[it.zig_index - 1];4203 const arg = args[it.zig_index - 1];
...@@ -7212,11 +7212,17 @@ pub const FuncGen = struct {...@@ -7212,11 +7212,17 @@ pub const FuncGen = struct {
7212 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {7212 fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
7213 if (self.liveness.isUnused(inst)) return null;7213 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
7215 const llvm_i32 = self.context.intType(32);7222 const llvm_i32 = self.context.intType(32);
7216 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});7223 const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{});
7217 const params = [_]*const llvm.Value{llvm_i32.constNull()};7224 const params = [_]*const llvm.Value{llvm_i32.constNull()};
7218 const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");7225 const ptr_val = self.builder.buildCall(llvm_fn, &params, params.len, .Fast, .Auto, "");
7219 const llvm_usize = try self.dg.lowerType(Type.usize);
7220 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");7226 return self.builder.buildPtrToInt(ptr_val, llvm_usize, "");
7221 }7227 }
72227228
...@@ -8021,7 +8027,6 @@ pub const FuncGen = struct {...@@ -8021,7 +8027,6 @@ pub const FuncGen = struct {
8021 assert(union_obj.haveFieldTypes());8027 assert(union_obj.haveFieldTypes());
8022 const field = union_obj.fields.values()[extra.field_index];8028 const field = union_obj.fields.values()[extra.field_index];
8023 const field_llvm_ty = try self.dg.lowerType(field.ty);8029 const field_llvm_ty = try self.dg.lowerType(field.ty);
8024 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
8025 const field_size = field.ty.abiSize(target);8030 const field_size = field.ty.abiSize(target);
8026 const field_align = field.normalAlignment(target);8031 const field_align = field.normalAlignment(target);
80278032
...@@ -8044,6 +8049,7 @@ pub const FuncGen = struct {...@@ -8044,6 +8049,7 @@ pub const FuncGen = struct {
8044 const fields: [1]*const llvm.Type = .{payload};8049 const fields: [1]*const llvm.Type = .{payload};
8045 break :t self.context.structType(&fields, fields.len, .False);8050 break :t self.context.structType(&fields, fields.len, .False);
8046 }8051 }
8052 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
8047 var fields: [3]*const llvm.Type = undefined;8053 var fields: [3]*const llvm.Type = undefined;
8048 var fields_len: c_uint = 2;8054 var fields_len: c_uint = 2;
8049 if (layout.tag_align >= layout.payload_align) {8055 if (layout.tag_align >= layout.payload_align) {
...@@ -8100,6 +8106,7 @@ pub const FuncGen = struct {...@@ -8100,6 +8106,7 @@ pub const FuncGen = struct {
8100 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),8106 index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False),
8101 };8107 };
8102 const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, indices.len, "");8108 const field_ptr = self.builder.buildInBoundsGEP(casted_ptr, &indices, indices.len, "");
8109 const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty);
8103 const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False);8110 const llvm_tag = tag_llvm_ty.constInt(extra.field_index, .False);
8104 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);8111 const store_inst = self.builder.buildStore(llvm_tag, field_ptr);
8105 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(target));8112 store_inst.setAlignment(union_obj.tag_ty.abiAlignment(target));
...@@ -9004,10 +9011,26 @@ const ParamTypeIterator = struct {...@@ -9004,10 +9011,26 @@ const ParamTypeIterator = struct {
9004 slice,9011 slice,
9005 };9012 };
90069013
9007 fn next(it: *ParamTypeIterator) ?Lowering {9014 pub fn next(it: *ParamTypeIterator) ?Lowering {
9008 if (it.zig_index >= it.fn_info.param_types.len) return null;9015 if (it.zig_index >= it.fn_info.param_types.len) return null;
9009
9010 const ty = it.fn_info.param_types[it.zig_index];9016 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 {
9011 if (!ty.hasRuntimeBitsIgnoreComptime()) {9034 if (!ty.hasRuntimeBitsIgnoreComptime()) {
9012 it.zig_index += 1;9035 it.zig_index += 1;
9013 return .no_bits;9036 return .no_bits;
src/stage1/codegen.cpp+2-2
...@@ -6764,8 +6764,8 @@ static LLVMValueRef ir_render_return_address(CodeGen *g, Stage1Air *executable,...@@ -6764,8 +6764,8 @@ static LLVMValueRef ir_render_return_address(CodeGen *g, Stage1Air *executable,
6764 Stage1AirInstReturnAddress *instruction)6764 Stage1AirInstReturnAddress *instruction)
6765{6765{
6766 if ((target_is_wasm(g->zig_target) && g->zig_target->os != OsEmscripten) || target_is_bpf(g->zig_target)) {6766 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:6767 // LLVM 13 reports "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address"
6768 // "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address"6768 // https://github.com/ziglang/zig/issues/11946
6769 return LLVMConstNull(get_llvm_type(g, instruction->base.value->type));6769 return LLVMConstNull(get_llvm_type(g, instruction->base.value->type));
6770 }6770 }
67716771
src/target.zig+8
...@@ -283,6 +283,14 @@ pub fn supportsStackProbing(target: std.Target) bool {...@@ -283,6 +283,14 @@ pub fn supportsStackProbing(target: std.Target) bool {
283 (target.cpu.arch == .i386 or target.cpu.arch == .x86_64);283 (target.cpu.arch == .i386 or target.cpu.arch == .x86_64);
284}284}
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
286pub fn osToLLVM(os_tag: std.Target.Os.Tag) llvm.OSType {294pub fn osToLLVM(os_tag: std.Target.Os.Tag) llvm.OSType {
287 return switch (os_tag) {295 return switch (os_tag) {
288 .freestanding, .other, .opencl, .glsl450, .vulkan, .plan9 => .UnknownOS,296 .freestanding, .other, .opencl, .glsl450, .vulkan, .plan9 => .UnknownOS,