| author | |
| committer | |
| log | 5c4bbd0657d52b1b579036b9ee32418e8d706966 |
| tree | debda5e9a9dd98a8e1ad3339c2a19730e604b0d7 |
| parent | aea45bdf252c5040b1883e83014f31e2122427de |
| parent | f56f3c5824af17516bcf3a0559b98cdad20bd416 |
21 files changed, 212 insertions(+), 61 deletions(-)
lib/build_runner.zig+9-4| ... | ... | @@ -204,7 +204,11 @@ pub fn main() !void { |
| 204 | 204 | } else if (mem.eql(u8, arg, "--verbose-air")) { |
| 205 | 205 | builder.verbose_air = true; |
| 206 | 206 | } 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..]; | |
| 208 | 212 | } else if (mem.eql(u8, arg, "--verbose-cimport")) { |
| 209 | 213 | builder.verbose_cimport = true; |
| 210 | 214 | } 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 |
| 990 | 994 | \\ --debug-pkg-config Fail if unknown pkg-config flags encountered |
| 991 | 995 | \\ --verbose-link Enable compiler debug output for linking |
| 992 | 996 | \\ --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 | |
| 994 | 999 | \\ --verbose-cimport Enable compiler debug output for C imports |
| 995 | 1000 | \\ --verbose-cc Enable compiler debug output for C compilation |
| 996 | 1001 | \\ --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 |
| 1003 | 1008 | process.exit(1); |
| 1004 | 1009 | } |
| 1005 | 1010 | |
| 1006 | fn nextArg(args: [][]const u8, idx: *usize) ?[]const u8 { | |
| 1011 | fn nextArg(args: [][:0]const u8, idx: *usize) ?[:0]const u8 { | |
| 1007 | 1012 | if (idx.* >= args.len) return null; |
| 1008 | 1013 | defer idx.* += 1; |
| 1009 | 1014 | return args[idx.*]; |
| 1010 | 1015 | } |
| 1011 | 1016 | |
| 1012 | fn argsRest(args: [][]const u8, idx: usize) ?[][]const u8 { | |
| 1017 | fn argsRest(args: [][:0]const u8, idx: usize) ?[][:0]const u8 { | |
| 1013 | 1018 | if (idx >= args.len) return null; |
| 1014 | 1019 | return args[idx..]; |
| 1015 | 1020 | } |
lib/std/Build.zig+7-4| ... | ... | @@ -54,12 +54,13 @@ verbose: bool, |
| 54 | 54 | verbose_link: bool, |
| 55 | 55 | verbose_cc: bool, |
| 56 | 56 | verbose_air: bool, |
| 57 | verbose_llvm_ir: bool, | |
| 57 | verbose_llvm_ir: ?[]const u8, | |
| 58 | verbose_llvm_bc: ?[]const u8, | |
| 58 | 59 | verbose_cimport: bool, |
| 59 | 60 | verbose_llvm_cpu_features: bool, |
| 60 | 61 | reference_trace: ?u32 = null, |
| 61 | 62 | invalid_user_input: bool, |
| 62 | zig_exe: []const u8, | |
| 63 | zig_exe: [:0]const u8, | |
| 63 | 64 | default_step: *Step, |
| 64 | 65 | env_map: *EnvMap, |
| 65 | 66 | top_level_steps: std.StringArrayHashMapUnmanaged(*TopLevelStep), |
| ... | ... | @@ -183,7 +184,7 @@ pub const DirList = struct { |
| 183 | 184 | |
| 184 | 185 | pub fn create( |
| 185 | 186 | allocator: Allocator, |
| 186 | zig_exe: []const u8, | |
| 187 | zig_exe: [:0]const u8, | |
| 187 | 188 | build_root: Cache.Directory, |
| 188 | 189 | cache_root: Cache.Directory, |
| 189 | 190 | global_cache_root: Cache.Directory, |
| ... | ... | @@ -204,7 +205,8 @@ pub fn create( |
| 204 | 205 | .verbose_link = false, |
| 205 | 206 | .verbose_cc = false, |
| 206 | 207 | .verbose_air = false, |
| 207 | .verbose_llvm_ir = false, | |
| 208 | .verbose_llvm_ir = null, | |
| 209 | .verbose_llvm_bc = null, | |
| 208 | 210 | .verbose_cimport = false, |
| 209 | 211 | .verbose_llvm_cpu_features = false, |
| 210 | 212 | .invalid_user_input = false, |
| ... | ... | @@ -292,6 +294,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc |
| 292 | 294 | .verbose_cc = parent.verbose_cc, |
| 293 | 295 | .verbose_air = parent.verbose_air, |
| 294 | 296 | .verbose_llvm_ir = parent.verbose_llvm_ir, |
| 297 | .verbose_llvm_bc = parent.verbose_llvm_bc, | |
| 295 | 298 | .verbose_cimport = parent.verbose_cimport, |
| 296 | 299 | .verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features, |
| 297 | 300 | .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 { |
| 1438 | 1438 | |
| 1439 | 1439 | if (b.verbose_cimport) try zig_args.append("--verbose-cimport"); |
| 1440 | 1440 | 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})); | |
| 1442 | 1443 | if (b.verbose_link or self.verbose_link) try zig_args.append("--verbose-link"); |
| 1443 | 1444 | if (b.verbose_cc or self.verbose_cc) try zig_args.append("--verbose-cc"); |
| 1444 | 1445 | 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; |
| 16 | 16 | /// var a_clone = a; // creates a copy - the structure doesn't use any internal pointers |
| 17 | 17 | /// ``` |
| 18 | 18 | pub 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 | /// ``` | |
| 35 | pub fn BoundedArrayAligned( | |
| 36 | comptime T: type, | |
| 37 | comptime alignment: u29, | |
| 38 | comptime buffer_capacity: usize, | |
| 39 | ) type { | |
| 19 | 40 | return struct { |
| 20 | 41 | const Self = @This(); |
| 21 | buffer: [buffer_capacity]T = undefined, | |
| 42 | buffer: [buffer_capacity]T align(alignment) = undefined, | |
| 22 | 43 | len: usize = 0, |
| 23 | 44 | |
| 24 | 45 | /// Set the actual length of the slice. |
| ... | ... | @@ -30,15 +51,15 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type { |
| 30 | 51 | |
| 31 | 52 | /// View the internal array as a slice whose size was previously set. |
| 32 | 53 | 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, | |
| 35 | 56 | else => unreachable, |
| 36 | 57 | } { |
| 37 | 58 | return self.buffer[0..self.len]; |
| 38 | 59 | } |
| 39 | 60 | |
| 40 | 61 | /// 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 { | |
| 42 | 63 | return self.slice(); |
| 43 | 64 | } |
| 44 | 65 | |
| ... | ... | @@ -94,7 +115,7 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type { |
| 94 | 115 | |
| 95 | 116 | /// Resize the slice, adding `n` new elements, which have `undefined` values. |
| 96 | 117 | /// 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 { | |
| 98 | 119 | const prev_len = self.len; |
| 99 | 120 | try self.resize(self.len + n); |
| 100 | 121 | return self.slice()[prev_len..][0..n]; |
| ... | ... | @@ -118,7 +139,7 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type { |
| 118 | 139 | /// This can be useful for writing directly into it. |
| 119 | 140 | /// Note that such an operation must be followed up with a |
| 120 | 141 | /// call to `resize()` |
| 121 | pub fn unusedCapacitySlice(self: *Self) []T { | |
| 142 | pub fn unusedCapacitySlice(self: *Self) []align(alignment) T { | |
| 122 | 143 | return self.buffer[self.len..]; |
| 123 | 144 | } |
| 124 | 145 | |
| ... | ... | @@ -365,3 +386,15 @@ test "BoundedArray" { |
| 365 | 386 | try w.writeAll(s); |
| 366 | 387 | try testing.expectEqualStrings(s, a.constSlice()); |
| 367 | 388 | } |
| 389 | ||
| 390 | test "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) { |
| 215 | 215 | ffdhe6144 = 0x0103, |
| 216 | 216 | ffdhe8192 = 0x0104, |
| 217 | 217 | |
| 218 | // Hybrid post-quantum key agreements | |
| 219 | x25519_kyber512d00 = 0xFE30, | |
| 220 | x25519_kyber768d00 = 0xFE31, | |
| 221 | ||
| 218 | 222 | _, |
| 219 | 223 | }; |
| 220 | 224 |
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 |
| 158 | 158 | // Only possible to happen if the private key is all zeroes. |
| 159 | 159 | error.IdentityElement => return error.InsufficientEntropy, |
| 160 | 160 | }; |
| 161 | const kyber768_kp = crypto.kem.kyber_d00.Kyber768.KeyPair.create(null) catch {}; | |
| 161 | 162 | |
| 162 | 163 | const extensions_payload = |
| 163 | 164 | tls.extension(.supported_versions, [_]u8{ |
| ... | ... | @@ -175,6 +176,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 175 | 176 | .rsa_pkcs1_sha512, |
| 176 | 177 | .ed25519, |
| 177 | 178 | })) ++ tls.extension(.supported_groups, enum_array(tls.NamedGroup, &.{ |
| 179 | .x25519_kyber768d00, | |
| 178 | 180 | .secp256r1, |
| 179 | 181 | .x25519, |
| 180 | 182 | })) ++ tls.extension( |
| ... | ... | @@ -182,7 +184,9 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 182 | 184 | array(1, int2(@enumToInt(tls.NamedGroup.x25519)) ++ |
| 183 | 185 | array(1, x25519_kp.public_key) ++ |
| 184 | 186 | 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())), | |
| 186 | 190 | ) ++ |
| 187 | 191 | int2(@enumToInt(tls.ExtensionType.server_name)) ++ |
| 188 | 192 | 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 |
| 274 | 278 | const extensions_size = hsd.decode(u16); |
| 275 | 279 | var all_extd = try hsd.sub(extensions_size); |
| 276 | 280 | var supported_version: u16 = 0; |
| 277 | var shared_key: [32]u8 = undefined; | |
| 281 | var shared_key: []const u8 = undefined; | |
| 278 | 282 | var have_shared_key = false; |
| 279 | 283 | while (!all_extd.eof()) { |
| 280 | 284 | try all_extd.ensure(2 + 2); |
| ... | ... | @@ -295,14 +299,29 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 295 | 299 | const key_size = extd.decode(u16); |
| 296 | 300 | try extd.ensure(key_size); |
| 297 | 301 | 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 | }, | |
| 298 | 316 | .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); | |
| 301 | 320 | |
| 302 | shared_key = crypto.dh.X25519.scalarmult( | |
| 321 | shared_key = &(crypto.dh.X25519.scalarmult( | |
| 303 | 322 | x25519_kp.secret_key, |
| 304 | 323 | server_pub_key.*, |
| 305 | ) catch return error.TlsDecryptFailure; | |
| 324 | ) catch return error.TlsDecryptFailure); | |
| 306 | 325 | }, |
| 307 | 326 | .secp256r1 => { |
| 308 | 327 | 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 |
| 314 | 333 | const mul = pk.p.mulPublic(secp256r1_kp.secret_key.bytes, .Big) catch { |
| 315 | 334 | return error.TlsDecryptFailure; |
| 316 | 335 | }; |
| 317 | shared_key = mul.affineCoordinates().x.toBytes(.Big); | |
| 336 | shared_key = &mul.affineCoordinates().x.toBytes(.Big); | |
| 318 | 337 | }, |
| 319 | 338 | else => { |
| 320 | 339 | return error.TlsIllegalParameter; |
| ... | ... | @@ -358,7 +377,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In |
| 358 | 377 | const early_secret = P.Hkdf.extract(&[1]u8{0}, &zeroes); |
| 359 | 378 | const empty_hash = tls.emptyHash(P.Hash); |
| 360 | 379 | 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); | |
| 362 | 381 | const ap_derived_secret = hkdfExpandLabel(P.Hkdf, p.handshake_secret, "derived", &empty_hash, P.Hash.digest_length); |
| 363 | 382 | p.master_secret = P.Hkdf.extract(&ap_derived_secret, &zeroes); |
| 364 | 383 | 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 { |
| 741 | 741 | return Stream{ .handle = sockfd }; |
| 742 | 742 | } |
| 743 | 743 | |
| 744 | const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || error{ | |
| 744 | const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || std.os.SetSockOptError || error{ | |
| 745 | 745 | // TODO: break this up into error sets from the various underlying functions |
| 746 | 746 | |
| 747 | 747 | TemporaryNameServerFailure, |
| ... | ... | @@ -1534,15 +1534,10 @@ fn resMSendRc( |
| 1534 | 1534 | ns[i] = iplit.addr; |
| 1535 | 1535 | assert(ns[i].getPort() == 53); |
| 1536 | 1536 | if (iplit.addr.any.family != os.AF.INET) { |
| 1537 | sl = @sizeOf(os.sockaddr.in6); | |
| 1538 | 1537 | family = os.AF.INET6; |
| 1539 | 1538 | } |
| 1540 | 1539 | } |
| 1541 | 1540 | |
| 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; | |
| 1546 | 1541 | const flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC | os.SOCK.NONBLOCK; |
| 1547 | 1542 | const fd = os.socket(family, flags, 0) catch |err| switch (err) { |
| 1548 | 1543 | error.AddressFamilyNotSupported => blk: { |
| ... | ... | @@ -1556,27 +1551,35 @@ fn resMSendRc( |
| 1556 | 1551 | else => |e| return e, |
| 1557 | 1552 | }; |
| 1558 | 1553 | defer os.closeSocket(fd); |
| 1559 | try os.bind(fd, &sa.any, sl); | |
| 1560 | 1554 | |
| 1561 | 1555 | // Past this point, there are no errors. Each individual query will |
| 1562 | 1556 | // yield either no reply (indicated by zero length) or an answer |
| 1563 | 1557 | // packet which is up to the caller to interpret. |
| 1564 | 1558 | |
| 1565 | 1559 | // 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); | |
| 1580 | 1583 | |
| 1581 | 1584 | var pfd = [1]os.pollfd{os.pollfd{ |
| 1582 | 1585 | .fd = fd, |
lib/std/std.zig+1| ... | ... | @@ -9,6 +9,7 @@ pub const AutoArrayHashMapUnmanaged = array_hash_map.AutoArrayHashMapUnmanaged; |
| 9 | 9 | pub const AutoHashMap = hash_map.AutoHashMap; |
| 10 | 10 | pub const AutoHashMapUnmanaged = hash_map.AutoHashMapUnmanaged; |
| 11 | 11 | pub const BoundedArray = @import("bounded_array.zig").BoundedArray; |
| 12 | pub const BoundedArrayAligned = @import("bounded_array.zig").BoundedArrayAligned; | |
| 12 | 13 | pub const Build = @import("Build.zig"); |
| 13 | 14 | pub const BufMap = @import("buf_map.zig").BufMap; |
| 14 | 15 | pub const BufSet = @import("buf_set.zig").BufSet; |
src/Compilation.zig+7-2| ... | ... | @@ -86,7 +86,8 @@ clang_preprocessor_mode: ClangPreprocessorMode, |
| 86 | 86 | /// Whether to print clang argvs to stdout. |
| 87 | 87 | verbose_cc: bool, |
| 88 | 88 | verbose_air: bool, |
| 89 | verbose_llvm_ir: bool, | |
| 89 | verbose_llvm_ir: ?[]const u8, | |
| 90 | verbose_llvm_bc: ?[]const u8, | |
| 90 | 91 | verbose_cimport: bool, |
| 91 | 92 | verbose_llvm_cpu_features: bool, |
| 92 | 93 | disable_c_depfile: bool, |
| ... | ... | @@ -585,7 +586,8 @@ pub const InitOptions = struct { |
| 585 | 586 | verbose_cc: bool = false, |
| 586 | 587 | verbose_link: bool = false, |
| 587 | 588 | verbose_air: bool = false, |
| 588 | verbose_llvm_ir: bool = false, | |
| 589 | verbose_llvm_ir: ?[]const u8 = null, | |
| 590 | verbose_llvm_bc: ?[]const u8 = null, | |
| 589 | 591 | verbose_cimport: bool = false, |
| 590 | 592 | verbose_llvm_cpu_features: bool = false, |
| 591 | 593 | is_test: bool = false, |
| ... | ... | @@ -1559,6 +1561,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1559 | 1561 | .verbose_cc = options.verbose_cc, |
| 1560 | 1562 | .verbose_air = options.verbose_air, |
| 1561 | 1563 | .verbose_llvm_ir = options.verbose_llvm_ir, |
| 1564 | .verbose_llvm_bc = options.verbose_llvm_bc, | |
| 1562 | 1565 | .verbose_cimport = options.verbose_cimport, |
| 1563 | 1566 | .verbose_llvm_cpu_features = options.verbose_llvm_cpu_features, |
| 1564 | 1567 | .disable_c_depfile = options.disable_c_depfile, |
| ... | ... | @@ -5349,6 +5352,7 @@ fn buildOutputFromZig( |
| 5349 | 5352 | .verbose_link = comp.bin_file.options.verbose_link, |
| 5350 | 5353 | .verbose_air = comp.verbose_air, |
| 5351 | 5354 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 5355 | .verbose_llvm_bc = comp.verbose_llvm_bc, | |
| 5352 | 5356 | .verbose_cimport = comp.verbose_cimport, |
| 5353 | 5357 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 5354 | 5358 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| ... | ... | @@ -5426,6 +5430,7 @@ pub fn build_crt_file( |
| 5426 | 5430 | .verbose_link = comp.bin_file.options.verbose_link, |
| 5427 | 5431 | .verbose_air = comp.verbose_air, |
| 5428 | 5432 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 5433 | .verbose_llvm_bc = comp.verbose_llvm_bc, | |
| 5429 | 5434 | .verbose_cimport = comp.verbose_cimport, |
| 5430 | 5435 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 5431 | 5436 | .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 { |
| 4263 | 4263 | comp.emit_llvm_bc == null); |
| 4264 | 4264 | |
| 4265 | 4265 | 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); | |
| 4267 | 4267 | |
| 4268 | 4268 | if (no_bin_file and !dump_air and !dump_llvm_ir) return; |
| 4269 | 4269 | |
| ... | ... | @@ -6395,7 +6395,7 @@ pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void { |
| 6395 | 6395 | comp.emit_llvm_ir == null and |
| 6396 | 6396 | comp.emit_llvm_bc == null); |
| 6397 | 6397 | |
| 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); | |
| 6399 | 6399 | |
| 6400 | 6400 | if (no_bin_file and !dump_llvm_ir) return; |
| 6401 | 6401 |
src/Sema.zig+12-3| ... | ... | @@ -4712,6 +4712,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 4712 | 4712 | .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}), |
| 4713 | 4713 | } |
| 4714 | 4714 | |
| 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 | ||
| 4715 | 4720 | const elem_ty = operand_ty.elemType2(); |
| 4716 | 4721 | if (try sema.resolveMaybeUndefVal(operand)) |val| { |
| 4717 | 4722 | if (val.isUndef()) { |
| ... | ... | @@ -15449,9 +15454,13 @@ fn zirRetAddr( |
| 15449 | 15454 | block: *Block, |
| 15450 | 15455 | extended: Zir.Inst.Extended.InstData, |
| 15451 | 15456 | ) 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 | } | |
| 15455 | 15464 | } |
| 15456 | 15465 | |
| 15457 | 15466 | fn zirFrameAddress( |
src/codegen/llvm.zig+29-2| ... | ... | @@ -756,8 +756,35 @@ pub const Object = struct { |
| 756 | 756 | dib.finalize(); |
| 757 | 757 | } |
| 758 | 758 | |
| 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 | } | |
| 761 | 788 | } |
| 762 | 789 | |
| 763 | 790 | var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa); |
src/codegen/llvm/bindings.zig+3| ... | ... | @@ -422,6 +422,9 @@ pub const Module = opaque { |
| 422 | 422 | |
| 423 | 423 | pub const printModuleToFile = LLVMPrintModuleToFile; |
| 424 | 424 | 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; | |
| 425 | 428 | }; |
| 426 | 429 | |
| 427 | 430 | pub const lookupIntrinsicID = LLVMLookupIntrinsicID; |
src/glibc.zig+1| ... | ... | @@ -1097,6 +1097,7 @@ fn buildSharedLib( |
| 1097 | 1097 | .verbose_link = comp.bin_file.options.verbose_link, |
| 1098 | 1098 | .verbose_air = comp.verbose_air, |
| 1099 | 1099 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 1100 | .verbose_llvm_bc = comp.verbose_llvm_bc, | |
| 1100 | 1101 | .verbose_cimport = comp.verbose_cimport, |
| 1101 | 1102 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 1102 | 1103 | .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 { |
| 250 | 250 | .verbose_link = comp.bin_file.options.verbose_link, |
| 251 | 251 | .verbose_air = comp.verbose_air, |
| 252 | 252 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 253 | .verbose_llvm_bc = comp.verbose_llvm_bc, | |
| 253 | 254 | .verbose_cimport = comp.verbose_cimport, |
| 254 | 255 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 255 | 256 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
| ... | ... | @@ -410,6 +411,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void { |
| 410 | 411 | .verbose_link = comp.bin_file.options.verbose_link, |
| 411 | 412 | .verbose_air = comp.verbose_air, |
| 412 | 413 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 414 | .verbose_llvm_bc = comp.verbose_llvm_bc, | |
| 413 | 415 | .verbose_cimport = comp.verbose_cimport, |
| 414 | 416 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 415 | 417 | .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 { |
| 226 | 226 | .verbose_link = comp.bin_file.options.verbose_link, |
| 227 | 227 | .verbose_air = comp.verbose_air, |
| 228 | 228 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 229 | .verbose_llvm_bc = comp.verbose_llvm_bc, | |
| 229 | 230 | .verbose_cimport = comp.verbose_cimport, |
| 230 | 231 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 231 | 232 | .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 { |
| 122 | 122 | .verbose_link = comp.bin_file.options.verbose_link, |
| 123 | 123 | .verbose_air = comp.verbose_air, |
| 124 | 124 | .verbose_llvm_ir = comp.verbose_llvm_ir, |
| 125 | .verbose_llvm_bc = comp.verbose_llvm_bc, | |
| 125 | 126 | .verbose_cimport = comp.verbose_cimport, |
| 126 | 127 | .verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features, |
| 127 | 128 | .clang_passthrough_mode = comp.clang_passthrough_mode, |
src/main.zig+15-8| ... | ... | @@ -370,10 +370,10 @@ const usage_build_generic = |
| 370 | 370 | \\ -fno-emit-bin Do not output machine code |
| 371 | 371 | \\ -femit-asm[=path] Output .s (assembly code) |
| 372 | 372 | \\ -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 | |
| 377 | 377 | \\ -femit-h[=path] Generate a C header file (.h) |
| 378 | 378 | \\ -fno-emit-h (default) Do not generate a C header file (.h) |
| 379 | 379 | \\ -femit-docs[=path] Create a docs/ dir with html documentation |
| ... | ... | @@ -555,13 +555,14 @@ const usage_build_generic = |
| 555 | 555 | \\ --test-runner [path] Specify a custom test runner |
| 556 | 556 | \\ |
| 557 | 557 | \\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 | |
| 559 | 559 | \\ -ftime-report Print timing diagnostics |
| 560 | 560 | \\ -fstack-report Print stack size diagnostics |
| 561 | 561 | \\ --verbose-link Display linker invocations |
| 562 | 562 | \\ --verbose-cc Display C compiler invocations |
| 563 | 563 | \\ --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 | |
| 565 | 566 | \\ --verbose-cimport Enable compiler debug output for C imports |
| 566 | 567 | \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features |
| 567 | 568 | \\ --debug-log [scope] Enable printing debug/info log messages for scope |
| ... | ... | @@ -704,7 +705,8 @@ fn buildOutputType( |
| 704 | 705 | var verbose_link = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_LINK"); |
| 705 | 706 | var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_CC"); |
| 706 | 707 | 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; | |
| 708 | 710 | var verbose_cimport = false; |
| 709 | 711 | var verbose_llvm_cpu_features = false; |
| 710 | 712 | var time_report = false; |
| ... | ... | @@ -1441,7 +1443,11 @@ fn buildOutputType( |
| 1441 | 1443 | } else if (mem.eql(u8, arg, "--verbose-air")) { |
| 1442 | 1444 | verbose_air = true; |
| 1443 | 1445 | } 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..]; | |
| 1445 | 1451 | } else if (mem.eql(u8, arg, "--verbose-cimport")) { |
| 1446 | 1452 | verbose_cimport = true; |
| 1447 | 1453 | } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) { |
| ... | ... | @@ -3226,6 +3232,7 @@ fn buildOutputType( |
| 3226 | 3232 | .verbose_link = verbose_link, |
| 3227 | 3233 | .verbose_air = verbose_air, |
| 3228 | 3234 | .verbose_llvm_ir = verbose_llvm_ir, |
| 3235 | .verbose_llvm_bc = verbose_llvm_bc, | |
| 3229 | 3236 | .verbose_cimport = verbose_cimport, |
| 3230 | 3237 | .verbose_llvm_cpu_features = verbose_llvm_cpu_features, |
| 3231 | 3238 | .machine_code_model = machine_code_model, |
test/behavior.zig+1| ... | ... | @@ -191,6 +191,7 @@ test { |
| 191 | 191 | _ = @import("behavior/pub_enum.zig"); |
| 192 | 192 | _ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig"); |
| 193 | 193 | _ = @import("behavior/reflection.zig"); |
| 194 | _ = @import("behavior/return_address.zig"); | |
| 194 | 195 | _ = @import("behavior/saturating_arithmetic.zig"); |
| 195 | 196 | _ = @import("behavior/select.zig"); |
| 196 | 197 | _ = @import("behavior/shuffle.zig"); |
test/behavior/comptime_memory.zig+8| ... | ... | @@ -420,3 +420,11 @@ test "mutate entire slice at comptime" { |
| 420 | 420 | buf[1..3].* = x; |
| 421 | 421 | } |
| 422 | 422 | } |
| 423 | ||
| 424 | test "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 @@ |
| 1 | const builtin = @import("builtin"); | |
| 2 | const testing = @import("std").testing; | |
| 3 | ||
| 4 | fn retAddr() usize { | |
| 5 | return @returnAddress(); | |
| 6 | } | |
| 7 | ||
| 8 | test "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 | } |