authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-17 14:55:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-03-17 14:55:22-07:00
log5c4bbd0657d52b1b579036b9ee32418e8d706966
treedebda5e9a9dd98a8e1ad3339c2a19730e604b0d7
parentaea45bdf252c5040b1883e83014f31e2122427de
parentf56f3c5824af17516bcf3a0559b98cdad20bd416

Merge remote-tracking branch 'origin/master' into llvm16


21 files changed, 212 insertions(+), 61 deletions(-)

lib/build_runner.zig+9-4
......@@ -204,7 +204,11 @@ pub fn main() !void {
204204 } else if (mem.eql(u8, arg, "--verbose-air")) {
205205 builder.verbose_air = true;
206206 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
207 builder.verbose_llvm_ir = true;
207 builder.verbose_llvm_ir = "-";
208 } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {
209 builder.verbose_llvm_ir = arg["--verbose-llvm-ir=".len..];
210 } else if (mem.eql(u8, arg, "--verbose-llvm-bc=")) {
211 builder.verbose_llvm_bc = arg["--verbose-llvm-bc=".len..];
208212 } else if (mem.eql(u8, arg, "--verbose-cimport")) {
209213 builder.verbose_cimport = true;
210214 } else if (mem.eql(u8, arg, "--verbose-cc")) {
......@@ -990,7 +994,8 @@ fn usage(builder: *std.Build, already_ran_build: bool, out_stream: anytype) !voi
990994 \\ --debug-pkg-config Fail if unknown pkg-config flags encountered
991995 \\ --verbose-link Enable compiler debug output for linking
992996 \\ --verbose-air Enable compiler debug output for Zig AIR
993 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
997 \\ --verbose-llvm-ir[=file] Enable compiler debug output for LLVM IR
998 \\ --verbose-llvm-bc=[file] Enable compiler debug output for LLVM BC
994999 \\ --verbose-cimport Enable compiler debug output for C imports
9951000 \\ --verbose-cc Enable compiler debug output for C compilation
9961001 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
......@@ -1003,13 +1008,13 @@ fn usageAndErr(builder: *std.Build, already_ran_build: bool, out_stream: anytype
10031008 process.exit(1);
10041009}
10051010
1006fn nextArg(args: [][]const u8, idx: *usize) ?[]const u8 {
1011fn nextArg(args: [][:0]const u8, idx: *usize) ?[:0]const u8 {
10071012 if (idx.* >= args.len) return null;
10081013 defer idx.* += 1;
10091014 return args[idx.*];
10101015}
10111016
1012fn argsRest(args: [][]const u8, idx: usize) ?[][]const u8 {
1017fn argsRest(args: [][:0]const u8, idx: usize) ?[][:0]const u8 {
10131018 if (idx >= args.len) return null;
10141019 return args[idx..];
10151020}
lib/std/Build.zig+7-4
......@@ -54,12 +54,13 @@ verbose: bool,
5454verbose_link: bool,
5555verbose_cc: bool,
5656verbose_air: bool,
57verbose_llvm_ir: bool,
57verbose_llvm_ir: ?[]const u8,
58verbose_llvm_bc: ?[]const u8,
5859verbose_cimport: bool,
5960verbose_llvm_cpu_features: bool,
6061reference_trace: ?u32 = null,
6162invalid_user_input: bool,
62zig_exe: []const u8,
63zig_exe: [:0]const u8,
6364default_step: *Step,
6465env_map: *EnvMap,
6566top_level_steps: std.StringArrayHashMapUnmanaged(*TopLevelStep),
......@@ -183,7 +184,7 @@ pub const DirList = struct {
183184
184185pub fn create(
185186 allocator: Allocator,
186 zig_exe: []const u8,
187 zig_exe: [:0]const u8,
187188 build_root: Cache.Directory,
188189 cache_root: Cache.Directory,
189190 global_cache_root: Cache.Directory,
......@@ -204,7 +205,8 @@ pub fn create(
204205 .verbose_link = false,
205206 .verbose_cc = false,
206207 .verbose_air = false,
207 .verbose_llvm_ir = false,
208 .verbose_llvm_ir = null,
209 .verbose_llvm_bc = null,
208210 .verbose_cimport = false,
209211 .verbose_llvm_cpu_features = false,
210212 .invalid_user_input = false,
......@@ -292,6 +294,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc
292294 .verbose_cc = parent.verbose_cc,
293295 .verbose_air = parent.verbose_air,
294296 .verbose_llvm_ir = parent.verbose_llvm_ir,
297 .verbose_llvm_bc = parent.verbose_llvm_bc,
295298 .verbose_cimport = parent.verbose_cimport,
296299 .verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features,
297300 .reference_trace = parent.reference_trace,
lib/std/Build/CompileStep.zig+2-1
......@@ -1438,7 +1438,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
14381438
14391439 if (b.verbose_cimport) try zig_args.append("--verbose-cimport");
14401440 if (b.verbose_air) try zig_args.append("--verbose-air");
1441 if (b.verbose_llvm_ir) try zig_args.append("--verbose-llvm-ir");
1441 if (b.verbose_llvm_ir) |path| try zig_args.append(b.fmt("--verbose-llvm-ir={s}", .{path}));
1442 if (b.verbose_llvm_bc) |path| try zig_args.append(b.fmt("--verbose-llvm-bc={s}", .{path}));
14421443 if (b.verbose_link or self.verbose_link) try zig_args.append("--verbose-link");
14431444 if (b.verbose_cc or self.verbose_cc) try zig_args.append("--verbose-cc");
14441445 if (b.verbose_llvm_cpu_features) try zig_args.append("--verbose-llvm-cpu-features");
lib/std/bounded_array.zig+39-6
......@@ -16,9 +16,30 @@ const testing = std.testing;
1616/// var a_clone = a; // creates a copy - the structure doesn't use any internal pointers
1717/// ```
1818pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
19 return BoundedArrayAligned(T, @alignOf(T), buffer_capacity);
20}
21
22/// A structure with an array, length and alignment, that can be used as a
23/// slice.
24///
25/// Useful to pass around small explicitly-aligned arrays whose exact size is
26/// only known at runtime, but whose maximum size is known at comptime, without
27/// requiring an `Allocator`.
28/// ```zig
29// var a = try BoundedArrayAligned(u8, 16, 2).init(0);
30// try a.append(255);
31// try a.append(255);
32// const b = @ptrCast(*const [1]u16, a.constSlice().ptr);
33// try testing.expectEqual(@as(u16, 65535), b[0]);
34/// ```
35pub fn BoundedArrayAligned(
36 comptime T: type,
37 comptime alignment: u29,
38 comptime buffer_capacity: usize,
39) type {
1940 return struct {
2041 const Self = @This();
21 buffer: [buffer_capacity]T = undefined,
42 buffer: [buffer_capacity]T align(alignment) = undefined,
2243 len: usize = 0,
2344
2445 /// Set the actual length of the slice.
......@@ -30,15 +51,15 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
3051
3152 /// View the internal array as a slice whose size was previously set.
3253 pub fn slice(self: anytype) switch (@TypeOf(&self.buffer)) {
33 *[buffer_capacity]T => []T,
34 *const [buffer_capacity]T => []const T,
54 *align(alignment) [buffer_capacity]T => []align(alignment) T,
55 *align(alignment) const [buffer_capacity]T => []align(alignment) const T,
3556 else => unreachable,
3657 } {
3758 return self.buffer[0..self.len];
3859 }
3960
4061 /// View the internal array as a constant slice whose size was previously set.
41 pub fn constSlice(self: *const Self) []const T {
62 pub fn constSlice(self: *const Self) []align(alignment) const T {
4263 return self.slice();
4364 }
4465
......@@ -94,7 +115,7 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
94115
95116 /// Resize the slice, adding `n` new elements, which have `undefined` values.
96117 /// The return value is a slice pointing to the uninitialized elements.
97 pub fn addManyAsArray(self: *Self, comptime n: usize) error{Overflow}!*[n]T {
118 pub fn addManyAsArray(self: *Self, comptime n: usize) error{Overflow}!*align(alignment) [n]T {
98119 const prev_len = self.len;
99120 try self.resize(self.len + n);
100121 return self.slice()[prev_len..][0..n];
......@@ -118,7 +139,7 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
118139 /// This can be useful for writing directly into it.
119140 /// Note that such an operation must be followed up with a
120141 /// call to `resize()`
121 pub fn unusedCapacitySlice(self: *Self) []T {
142 pub fn unusedCapacitySlice(self: *Self) []align(alignment) T {
122143 return self.buffer[self.len..];
123144 }
124145
......@@ -365,3 +386,15 @@ test "BoundedArray" {
365386 try w.writeAll(s);
366387 try testing.expectEqualStrings(s, a.constSlice());
367388}
389
390test "BoundedArrayAligned" {
391 var a = try BoundedArrayAligned(u8, 16, 4).init(0);
392 try a.append(0);
393 try a.append(0);
394 try a.append(255);
395 try a.append(255);
396
397 const b = @ptrCast(*const [2]u16, a.constSlice().ptr);
398 try testing.expectEqual(@as(u16, 0), b[0]);
399 try testing.expectEqual(@as(u16, 65535), b[1]);
400}
lib/std/crypto/tls.zig+4
......@@ -215,6 +215,10 @@ pub const NamedGroup = enum(u16) {
215215 ffdhe6144 = 0x0103,
216216 ffdhe8192 = 0x0104,
217217
218 // Hybrid post-quantum key agreements
219 x25519_kyber512d00 = 0xFE30,
220 x25519_kyber768d00 = 0xFE31,
221
218222 _,
219223};
220224
lib/std/crypto/tls/Client.zig+27-8
......@@ -158,6 +158,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
158158 // Only possible to happen if the private key is all zeroes.
159159 error.IdentityElement => return error.InsufficientEntropy,
160160 };
161 const kyber768_kp = crypto.kem.kyber_d00.Kyber768.KeyPair.create(null) catch {};
161162
162163 const extensions_payload =
163164 tls.extension(.supported_versions, [_]u8{
......@@ -175,6 +176,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
175176 .rsa_pkcs1_sha512,
176177 .ed25519,
177178 })) ++ tls.extension(.supported_groups, enum_array(tls.NamedGroup, &.{
179 .x25519_kyber768d00,
178180 .secp256r1,
179181 .x25519,
180182 })) ++ tls.extension(
......@@ -182,7 +184,9 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
182184 array(1, int2(@enumToInt(tls.NamedGroup.x25519)) ++
183185 array(1, x25519_kp.public_key) ++
184186 int2(@enumToInt(tls.NamedGroup.secp256r1)) ++
185 array(1, secp256r1_kp.public_key.toUncompressedSec1())),
187 array(1, secp256r1_kp.public_key.toUncompressedSec1()) ++
188 int2(@enumToInt(tls.NamedGroup.x25519_kyber768d00)) ++
189 array(1, x25519_kp.public_key ++ kyber768_kp.public_key.toBytes())),
186190 ) ++
187191 int2(@enumToInt(tls.ExtensionType.server_name)) ++
188192 int2(host_len + 5) ++ // byte length of this extension payload
......@@ -274,7 +278,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
274278 const extensions_size = hsd.decode(u16);
275279 var all_extd = try hsd.sub(extensions_size);
276280 var supported_version: u16 = 0;
277 var shared_key: [32]u8 = undefined;
281 var shared_key: []const u8 = undefined;
278282 var have_shared_key = false;
279283 while (!all_extd.eof()) {
280284 try all_extd.ensure(2 + 2);
......@@ -295,14 +299,29 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
295299 const key_size = extd.decode(u16);
296300 try extd.ensure(key_size);
297301 switch (named_group) {
302 .x25519_kyber768d00 => {
303 const xksl = crypto.dh.X25519.public_length;
304 const hksl = xksl + crypto.kem.kyber_d00.Kyber768.ciphertext_length;
305 if (key_size != hksl)
306 return error.TlsIllegalParameter;
307 const server_ks = extd.array(hksl);
308
309 shared_key = &((crypto.dh.X25519.scalarmult(
310 x25519_kp.secret_key,
311 server_ks[0..xksl].*,
312 ) catch return error.TlsDecryptFailure) ++ (kyber768_kp.secret_key.decaps(
313 server_ks[xksl..hksl],
314 ) catch return error.TlsDecryptFailure));
315 },
298316 .x25519 => {
299 if (key_size != 32) return error.TlsIllegalParameter;
300 const server_pub_key = extd.array(32);
317 const ksl = crypto.dh.X25519.public_length;
318 if (key_size != ksl) return error.TlsIllegalParameter;
319 const server_pub_key = extd.array(ksl);
301320
302 shared_key = crypto.dh.X25519.scalarmult(
321 shared_key = &(crypto.dh.X25519.scalarmult(
303322 x25519_kp.secret_key,
304323 server_pub_key.*,
305 ) catch return error.TlsDecryptFailure;
324 ) catch return error.TlsDecryptFailure);
306325 },
307326 .secp256r1 => {
308327 const server_pub_key = extd.slice(key_size);
......@@ -314,7 +333,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
314333 const mul = pk.p.mulPublic(secp256r1_kp.secret_key.bytes, .Big) catch {
315334 return error.TlsDecryptFailure;
316335 };
317 shared_key = mul.affineCoordinates().x.toBytes(.Big);
336 shared_key = &mul.affineCoordinates().x.toBytes(.Big);
318337 },
319338 else => {
320339 return error.TlsIllegalParameter;
......@@ -358,7 +377,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
358377 const early_secret = P.Hkdf.extract(&[1]u8{0}, &zeroes);
359378 const empty_hash = tls.emptyHash(P.Hash);
360379 const hs_derived_secret = hkdfExpandLabel(P.Hkdf, early_secret, "derived", &empty_hash, P.Hash.digest_length);
361 p.handshake_secret = P.Hkdf.extract(&hs_derived_secret, &shared_key);
380 p.handshake_secret = P.Hkdf.extract(&hs_derived_secret, shared_key);
362381 const ap_derived_secret = hkdfExpandLabel(P.Hkdf, p.handshake_secret, "derived", &empty_hash, P.Hash.digest_length);
363382 p.master_secret = P.Hkdf.extract(&ap_derived_secret, &zeroes);
364383 const client_secret = hkdfExpandLabel(P.Hkdf, p.handshake_secret, "c hs traffic", &hello_hash, P.Hash.digest_length);
lib/std/net.zig+24-21
......@@ -741,7 +741,7 @@ pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream {
741741 return Stream{ .handle = sockfd };
742742}
743743
744const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || error{
744const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || std.os.SetSockOptError || error{
745745 // TODO: break this up into error sets from the various underlying functions
746746
747747 TemporaryNameServerFailure,
......@@ -1534,15 +1534,10 @@ fn resMSendRc(
15341534 ns[i] = iplit.addr;
15351535 assert(ns[i].getPort() == 53);
15361536 if (iplit.addr.any.family != os.AF.INET) {
1537 sl = @sizeOf(os.sockaddr.in6);
15381537 family = os.AF.INET6;
15391538 }
15401539 }
15411540
1542 // Get local address and open/bind a socket
1543 var sa: Address = undefined;
1544 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
1545 sa.any.family = family;
15461541 const flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC | os.SOCK.NONBLOCK;
15471542 const fd = os.socket(family, flags, 0) catch |err| switch (err) {
15481543 error.AddressFamilyNotSupported => blk: {
......@@ -1556,27 +1551,35 @@ fn resMSendRc(
15561551 else => |e| return e,
15571552 };
15581553 defer os.closeSocket(fd);
1559 try os.bind(fd, &sa.any, sl);
15601554
15611555 // Past this point, there are no errors. Each individual query will
15621556 // yield either no reply (indicated by zero length) or an answer
15631557 // packet which is up to the caller to interpret.
15641558
15651559 // Convert any IPv4 addresses in a mixed environment to v4-mapped
1566 // TODO
1567 //if (family == AF.INET6) {
1568 // setsockopt(fd, IPPROTO.IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
1569 // for (i=0; i<nns; i++) {
1570 // if (ns[i].sin.sin_family != AF.INET) continue;
1571 // memcpy(ns[i].sin6.sin6_addr.s6_addr+12,
1572 // &ns[i].sin.sin_addr, 4);
1573 // memcpy(ns[i].sin6.sin6_addr.s6_addr,
1574 // "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
1575 // ns[i].sin6.sin6_family = AF.INET6;
1576 // ns[i].sin6.sin6_flowinfo = 0;
1577 // ns[i].sin6.sin6_scope_id = 0;
1578 // }
1579 //}
1560 if (family == os.AF.INET6) {
1561 try os.setsockopt(
1562 fd,
1563 os.SOL.IPV6,
1564 os.linux.IPV6.V6ONLY,
1565 &mem.toBytes(@as(c_int, 0)),
1566 );
1567 for (0..ns.len) |i| {
1568 if (ns[i].any.family != os.AF.INET) continue;
1569 mem.writeIntNative(u32, ns[i].in6.sa.addr[12..], ns[i].in.sa.addr);
1570 mem.copy(u8, ns[i].in6.sa.addr[0..12], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
1571 ns[i].any.family = os.AF.INET6;
1572 ns[i].in6.sa.flowinfo = 0;
1573 ns[i].in6.sa.scope_id = 0;
1574 }
1575 sl = @sizeOf(os.sockaddr.in6);
1576 }
1577
1578 // Get local address and open/bind a socket
1579 var sa: Address = undefined;
1580 @memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
1581 sa.any.family = family;
1582 try os.bind(fd, &sa.any, sl);
15801583
15811584 var pfd = [1]os.pollfd{os.pollfd{
15821585 .fd = fd,
lib/std/std.zig+1
......@@ -9,6 +9,7 @@ pub const AutoArrayHashMapUnmanaged = array_hash_map.AutoArrayHashMapUnmanaged;
99pub const AutoHashMap = hash_map.AutoHashMap;
1010pub const AutoHashMapUnmanaged = hash_map.AutoHashMapUnmanaged;
1111pub const BoundedArray = @import("bounded_array.zig").BoundedArray;
12pub const BoundedArrayAligned = @import("bounded_array.zig").BoundedArrayAligned;
1213pub const Build = @import("Build.zig");
1314pub const BufMap = @import("buf_map.zig").BufMap;
1415pub const BufSet = @import("buf_set.zig").BufSet;
src/Compilation.zig+7-2
......@@ -86,7 +86,8 @@ clang_preprocessor_mode: ClangPreprocessorMode,
8686/// Whether to print clang argvs to stdout.
8787verbose_cc: bool,
8888verbose_air: bool,
89verbose_llvm_ir: bool,
89verbose_llvm_ir: ?[]const u8,
90verbose_llvm_bc: ?[]const u8,
9091verbose_cimport: bool,
9192verbose_llvm_cpu_features: bool,
9293disable_c_depfile: bool,
......@@ -585,7 +586,8 @@ pub const InitOptions = struct {
585586 verbose_cc: bool = false,
586587 verbose_link: bool = false,
587588 verbose_air: bool = false,
588 verbose_llvm_ir: bool = false,
589 verbose_llvm_ir: ?[]const u8 = null,
590 verbose_llvm_bc: ?[]const u8 = null,
589591 verbose_cimport: bool = false,
590592 verbose_llvm_cpu_features: bool = false,
591593 is_test: bool = false,
......@@ -1559,6 +1561,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
15591561 .verbose_cc = options.verbose_cc,
15601562 .verbose_air = options.verbose_air,
15611563 .verbose_llvm_ir = options.verbose_llvm_ir,
1564 .verbose_llvm_bc = options.verbose_llvm_bc,
15621565 .verbose_cimport = options.verbose_cimport,
15631566 .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features,
15641567 .disable_c_depfile = options.disable_c_depfile,
......@@ -5349,6 +5352,7 @@ fn buildOutputFromZig(
53495352 .verbose_link = comp.bin_file.options.verbose_link,
53505353 .verbose_air = comp.verbose_air,
53515354 .verbose_llvm_ir = comp.verbose_llvm_ir,
5355 .verbose_llvm_bc = comp.verbose_llvm_bc,
53525356 .verbose_cimport = comp.verbose_cimport,
53535357 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
53545358 .clang_passthrough_mode = comp.clang_passthrough_mode,
......@@ -5426,6 +5430,7 @@ pub fn build_crt_file(
54265430 .verbose_link = comp.bin_file.options.verbose_link,
54275431 .verbose_air = comp.verbose_air,
54285432 .verbose_llvm_ir = comp.verbose_llvm_ir,
5433 .verbose_llvm_bc = comp.verbose_llvm_bc,
54295434 .verbose_cimport = comp.verbose_cimport,
54305435 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
54315436 .clang_passthrough_mode = comp.clang_passthrough_mode,
src/Module.zig+2-2
......@@ -4263,7 +4263,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
42634263 comp.emit_llvm_bc == null);
42644264
42654265 const dump_air = builtin.mode == .Debug and comp.verbose_air;
4266 const dump_llvm_ir = builtin.mode == .Debug and comp.verbose_llvm_ir;
4266 const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
42674267
42684268 if (no_bin_file and !dump_air and !dump_llvm_ir) return;
42694269
......@@ -6395,7 +6395,7 @@ pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void {
63956395 comp.emit_llvm_ir == null and
63966396 comp.emit_llvm_bc == null);
63976397
6398 const dump_llvm_ir = builtin.mode == .Debug and comp.verbose_llvm_ir;
6398 const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
63996399
64006400 if (no_bin_file and !dump_llvm_ir) return;
64016401
src/Sema.zig+12-3
......@@ -4712,6 +4712,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
47124712 .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}),
47134713 }
47144714
4715 if ((try sema.typeHasOnePossibleValue(operand_ty.childType())) != null) {
4716 // No need to validate the actual pointer value, we don't need it!
4717 return;
4718 }
4719
47154720 const elem_ty = operand_ty.elemType2();
47164721 if (try sema.resolveMaybeUndefVal(operand)) |val| {
47174722 if (val.isUndef()) {
......@@ -15449,9 +15454,13 @@ fn zirRetAddr(
1544915454 block: *Block,
1545015455 extended: Zir.Inst.Extended.InstData,
1545115456) CompileError!Air.Inst.Ref {
15452 const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
15453 try sema.requireRuntimeBlock(block, src, null);
15454 return try block.addNoOp(.ret_addr);
15457 _ = extended;
15458 if (block.is_comptime) {
15459 // TODO: we could give a meaningful lazy value here. #14938
15460 return sema.addIntUnsigned(Type.usize, 0);
15461 } else {
15462 return block.addNoOp(.ret_addr);
15463 }
1545515464}
1545615465
1545715466fn zirFrameAddress(
src/codegen/llvm.zig+29-2
......@@ -756,8 +756,35 @@ pub const Object = struct {
756756 dib.finalize();
757757 }
758758
759 if (comp.verbose_llvm_ir) {
760 self.llvm_module.dump();
759 if (comp.verbose_llvm_ir) |path| {
760 if (std.mem.eql(u8, path, "-")) {
761 self.llvm_module.dump();
762 } else {
763 const path_z = try comp.gpa.dupeZ(u8, path);
764 defer comp.gpa.free(path_z);
765
766 var error_message: [*:0]const u8 = undefined;
767
768 if (self.llvm_module.printModuleToFile(path_z, &error_message).toBool()) {
769 defer llvm.disposeMessage(error_message);
770
771 log.err("dump LLVM module failed ir={s}: {s}", .{
772 path, error_message,
773 });
774 }
775 }
776 }
777
778 if (comp.verbose_llvm_bc) |path| {
779 const path_z = try comp.gpa.dupeZ(u8, path);
780 defer comp.gpa.free(path_z);
781
782 const error_code = self.llvm_module.writeBitcodeToFile(path_z);
783 if (error_code != 0) {
784 log.err("dump LLVM module failed bc={s}: {d}", .{
785 path, error_code,
786 });
787 }
761788 }
762789
763790 var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
src/codegen/llvm/bindings.zig+3
......@@ -422,6 +422,9 @@ pub const Module = opaque {
422422
423423 pub const printModuleToFile = LLVMPrintModuleToFile;
424424 extern fn LLVMPrintModuleToFile(M: *Module, Filename: [*:0]const u8, ErrorMessage: *[*:0]const u8) Bool;
425
426 pub const writeBitcodeToFile = LLVMWriteBitcodeToFile;
427 extern fn LLVMWriteBitcodeToFile(M: *Module, Path: [*:0]const u8) c_int;
425428};
426429
427430pub const lookupIntrinsicID = LLVMLookupIntrinsicID;
src/glibc.zig+1
......@@ -1097,6 +1097,7 @@ fn buildSharedLib(
10971097 .verbose_link = comp.bin_file.options.verbose_link,
10981098 .verbose_air = comp.verbose_air,
10991099 .verbose_llvm_ir = comp.verbose_llvm_ir,
1100 .verbose_llvm_bc = comp.verbose_llvm_bc,
11001101 .verbose_cimport = comp.verbose_cimport,
11011102 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
11021103 .clang_passthrough_mode = comp.clang_passthrough_mode,
src/libcxx.zig+2
......@@ -250,6 +250,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
250250 .verbose_link = comp.bin_file.options.verbose_link,
251251 .verbose_air = comp.verbose_air,
252252 .verbose_llvm_ir = comp.verbose_llvm_ir,
253 .verbose_llvm_bc = comp.verbose_llvm_bc,
253254 .verbose_cimport = comp.verbose_cimport,
254255 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
255256 .clang_passthrough_mode = comp.clang_passthrough_mode,
......@@ -410,6 +411,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
410411 .verbose_link = comp.bin_file.options.verbose_link,
411412 .verbose_air = comp.verbose_air,
412413 .verbose_llvm_ir = comp.verbose_llvm_ir,
414 .verbose_llvm_bc = comp.verbose_llvm_bc,
413415 .verbose_cimport = comp.verbose_cimport,
414416 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
415417 .clang_passthrough_mode = comp.clang_passthrough_mode,
src/libtsan.zig+1
......@@ -226,6 +226,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
226226 .verbose_link = comp.bin_file.options.verbose_link,
227227 .verbose_air = comp.verbose_air,
228228 .verbose_llvm_ir = comp.verbose_llvm_ir,
229 .verbose_llvm_bc = comp.verbose_llvm_bc,
229230 .verbose_cimport = comp.verbose_cimport,
230231 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
231232 .clang_passthrough_mode = comp.clang_passthrough_mode,
src/libunwind.zig+1
......@@ -122,6 +122,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
122122 .verbose_link = comp.bin_file.options.verbose_link,
123123 .verbose_air = comp.verbose_air,
124124 .verbose_llvm_ir = comp.verbose_llvm_ir,
125 .verbose_llvm_bc = comp.verbose_llvm_bc,
125126 .verbose_cimport = comp.verbose_cimport,
126127 .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
127128 .clang_passthrough_mode = comp.clang_passthrough_mode,
src/main.zig+15-8
......@@ -370,10 +370,10 @@ const usage_build_generic =
370370 \\ -fno-emit-bin Do not output machine code
371371 \\ -femit-asm[=path] Output .s (assembly code)
372372 \\ -fno-emit-asm (default) Do not output .s (assembly code)
373 \\ -femit-llvm-ir[=path] Produce a .ll file with LLVM IR (requires LLVM extensions)
374 \\ -fno-emit-llvm-ir (default) Do not produce a .ll file with LLVM IR
375 \\ -femit-llvm-bc[=path] Produce a LLVM module as a .bc file (requires LLVM extensions)
376 \\ -fno-emit-llvm-bc (default) Do not produce a LLVM module as a .bc file
373 \\ -femit-llvm-ir[=path] Produce a .ll file with optimized LLVM IR (requires LLVM extensions)
374 \\ -fno-emit-llvm-ir (default) Do not produce a .ll file with optimized LLVM IR
375 \\ -femit-llvm-bc[=path] Produce an optimized LLVM module as a .bc file (requires LLVM extensions)
376 \\ -fno-emit-llvm-bc (default) Do not produce an optimized LLVM module as a .bc file
377377 \\ -femit-h[=path] Generate a C header file (.h)
378378 \\ -fno-emit-h (default) Do not generate a C header file (.h)
379379 \\ -femit-docs[=path] Create a docs/ dir with html documentation
......@@ -555,13 +555,14 @@ const usage_build_generic =
555555 \\ --test-runner [path] Specify a custom test runner
556556 \\
557557 \\Debug Options (Zig Compiler Development):
558 \\ -fopt-bisect-limit [limit] Only run [limit] first LLVM optimization passes
558 \\ -fopt-bisect-limit=[limit] Only run [limit] first LLVM optimization passes
559559 \\ -ftime-report Print timing diagnostics
560560 \\ -fstack-report Print stack size diagnostics
561561 \\ --verbose-link Display linker invocations
562562 \\ --verbose-cc Display C compiler invocations
563563 \\ --verbose-air Enable compiler debug output for Zig AIR
564 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
564 \\ --verbose-llvm-ir[=path] Enable compiler debug output for unoptimized LLVM IR
565 \\ --verbose-llvm-bc=[path] Enable compiler debug output for unoptimized LLVM BC
565566 \\ --verbose-cimport Enable compiler debug output for C imports
566567 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
567568 \\ --debug-log [scope] Enable printing debug/info log messages for scope
......@@ -704,7 +705,8 @@ fn buildOutputType(
704705 var verbose_link = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_LINK");
705706 var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_CC");
706707 var verbose_air = false;
707 var verbose_llvm_ir = false;
708 var verbose_llvm_ir: ?[]const u8 = null;
709 var verbose_llvm_bc: ?[]const u8 = null;
708710 var verbose_cimport = false;
709711 var verbose_llvm_cpu_features = false;
710712 var time_report = false;
......@@ -1441,7 +1443,11 @@ fn buildOutputType(
14411443 } else if (mem.eql(u8, arg, "--verbose-air")) {
14421444 verbose_air = true;
14431445 } else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
1444 verbose_llvm_ir = true;
1446 verbose_llvm_ir = "-";
1447 } else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {
1448 verbose_llvm_ir = arg["--verbose-llvm-ir=".len..];
1449 } else if (mem.startsWith(u8, arg, "--verbose-llvm-bc=")) {
1450 verbose_llvm_bc = arg["--verbose-llvm-bc=".len..];
14451451 } else if (mem.eql(u8, arg, "--verbose-cimport")) {
14461452 verbose_cimport = true;
14471453 } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
......@@ -3226,6 +3232,7 @@ fn buildOutputType(
32263232 .verbose_link = verbose_link,
32273233 .verbose_air = verbose_air,
32283234 .verbose_llvm_ir = verbose_llvm_ir,
3235 .verbose_llvm_bc = verbose_llvm_bc,
32293236 .verbose_cimport = verbose_cimport,
32303237 .verbose_llvm_cpu_features = verbose_llvm_cpu_features,
32313238 .machine_code_model = machine_code_model,
test/behavior.zig+1
......@@ -191,6 +191,7 @@ test {
191191 _ = @import("behavior/pub_enum.zig");
192192 _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
193193 _ = @import("behavior/reflection.zig");
194 _ = @import("behavior/return_address.zig");
194195 _ = @import("behavior/saturating_arithmetic.zig");
195196 _ = @import("behavior/select.zig");
196197 _ = @import("behavior/shuffle.zig");
test/behavior/comptime_memory.zig+8
......@@ -420,3 +420,11 @@ test "mutate entire slice at comptime" {
420420 buf[1..3].* = x;
421421 }
422422}
423
424test "dereference undefined pointer to zero-bit type" {
425 const p0: *void = undefined;
426 try testing.expectEqual({}, p0.*);
427
428 const p1: *[0]u32 = undefined;
429 try testing.expect(p1.*.len == 0);
430}
test/behavior/return_address.zig created+17
......@@ -0,0 +1,17 @@
1const builtin = @import("builtin");
2const testing = @import("std").testing;
3
4fn retAddr() usize {
5 return @returnAddress();
6}
7
8test "return address" {
9 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
10 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
11 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
12 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
13 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
14 _ = retAddr();
15 // TODO: #14938
16 try testing.expectEqual(0, comptime retAddr());
17}