mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
Merge remote-tracking branch 'origin/master' into llvm16
This commit is contained in:
commit
5c4bbd0657
@ -204,7 +204,11 @@ pub fn main() !void {
|
||||
} else if (mem.eql(u8, arg, "--verbose-air")) {
|
||||
builder.verbose_air = true;
|
||||
} else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
|
||||
builder.verbose_llvm_ir = true;
|
||||
builder.verbose_llvm_ir = "-";
|
||||
} else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {
|
||||
builder.verbose_llvm_ir = arg["--verbose-llvm-ir=".len..];
|
||||
} else if (mem.eql(u8, arg, "--verbose-llvm-bc=")) {
|
||||
builder.verbose_llvm_bc = arg["--verbose-llvm-bc=".len..];
|
||||
} else if (mem.eql(u8, arg, "--verbose-cimport")) {
|
||||
builder.verbose_cimport = true;
|
||||
} 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
|
||||
\\ --debug-pkg-config Fail if unknown pkg-config flags encountered
|
||||
\\ --verbose-link Enable compiler debug output for linking
|
||||
\\ --verbose-air Enable compiler debug output for Zig AIR
|
||||
\\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
|
||||
\\ --verbose-llvm-ir[=file] Enable compiler debug output for LLVM IR
|
||||
\\ --verbose-llvm-bc=[file] Enable compiler debug output for LLVM BC
|
||||
\\ --verbose-cimport Enable compiler debug output for C imports
|
||||
\\ --verbose-cc Enable compiler debug output for C compilation
|
||||
\\ --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
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
fn nextArg(args: [][]const u8, idx: *usize) ?[]const u8 {
|
||||
fn nextArg(args: [][:0]const u8, idx: *usize) ?[:0]const u8 {
|
||||
if (idx.* >= args.len) return null;
|
||||
defer idx.* += 1;
|
||||
return args[idx.*];
|
||||
}
|
||||
|
||||
fn argsRest(args: [][]const u8, idx: usize) ?[][]const u8 {
|
||||
fn argsRest(args: [][:0]const u8, idx: usize) ?[][:0]const u8 {
|
||||
if (idx >= args.len) return null;
|
||||
return args[idx..];
|
||||
}
|
||||
|
||||
@ -54,12 +54,13 @@ verbose: bool,
|
||||
verbose_link: bool,
|
||||
verbose_cc: bool,
|
||||
verbose_air: bool,
|
||||
verbose_llvm_ir: bool,
|
||||
verbose_llvm_ir: ?[]const u8,
|
||||
verbose_llvm_bc: ?[]const u8,
|
||||
verbose_cimport: bool,
|
||||
verbose_llvm_cpu_features: bool,
|
||||
reference_trace: ?u32 = null,
|
||||
invalid_user_input: bool,
|
||||
zig_exe: []const u8,
|
||||
zig_exe: [:0]const u8,
|
||||
default_step: *Step,
|
||||
env_map: *EnvMap,
|
||||
top_level_steps: std.StringArrayHashMapUnmanaged(*TopLevelStep),
|
||||
@ -183,7 +184,7 @@ pub const DirList = struct {
|
||||
|
||||
pub fn create(
|
||||
allocator: Allocator,
|
||||
zig_exe: []const u8,
|
||||
zig_exe: [:0]const u8,
|
||||
build_root: Cache.Directory,
|
||||
cache_root: Cache.Directory,
|
||||
global_cache_root: Cache.Directory,
|
||||
@ -204,7 +205,8 @@ pub fn create(
|
||||
.verbose_link = false,
|
||||
.verbose_cc = false,
|
||||
.verbose_air = false,
|
||||
.verbose_llvm_ir = false,
|
||||
.verbose_llvm_ir = null,
|
||||
.verbose_llvm_bc = null,
|
||||
.verbose_cimport = false,
|
||||
.verbose_llvm_cpu_features = false,
|
||||
.invalid_user_input = false,
|
||||
@ -292,6 +294,7 @@ fn createChildOnly(parent: *Build, dep_name: []const u8, build_root: Cache.Direc
|
||||
.verbose_cc = parent.verbose_cc,
|
||||
.verbose_air = parent.verbose_air,
|
||||
.verbose_llvm_ir = parent.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = parent.verbose_llvm_bc,
|
||||
.verbose_cimport = parent.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = parent.verbose_llvm_cpu_features,
|
||||
.reference_trace = parent.reference_trace,
|
||||
|
||||
@ -1438,7 +1438,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void {
|
||||
|
||||
if (b.verbose_cimport) try zig_args.append("--verbose-cimport");
|
||||
if (b.verbose_air) try zig_args.append("--verbose-air");
|
||||
if (b.verbose_llvm_ir) try zig_args.append("--verbose-llvm-ir");
|
||||
if (b.verbose_llvm_ir) |path| try zig_args.append(b.fmt("--verbose-llvm-ir={s}", .{path}));
|
||||
if (b.verbose_llvm_bc) |path| try zig_args.append(b.fmt("--verbose-llvm-bc={s}", .{path}));
|
||||
if (b.verbose_link or self.verbose_link) try zig_args.append("--verbose-link");
|
||||
if (b.verbose_cc or self.verbose_cc) try zig_args.append("--verbose-cc");
|
||||
if (b.verbose_llvm_cpu_features) try zig_args.append("--verbose-llvm-cpu-features");
|
||||
|
||||
@ -16,9 +16,30 @@ const testing = std.testing;
|
||||
/// var a_clone = a; // creates a copy - the structure doesn't use any internal pointers
|
||||
/// ```
|
||||
pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
||||
return BoundedArrayAligned(T, @alignOf(T), buffer_capacity);
|
||||
}
|
||||
|
||||
/// A structure with an array, length and alignment, that can be used as a
|
||||
/// slice.
|
||||
///
|
||||
/// Useful to pass around small explicitly-aligned arrays whose exact size is
|
||||
/// only known at runtime, but whose maximum size is known at comptime, without
|
||||
/// requiring an `Allocator`.
|
||||
/// ```zig
|
||||
// var a = try BoundedArrayAligned(u8, 16, 2).init(0);
|
||||
// try a.append(255);
|
||||
// try a.append(255);
|
||||
// const b = @ptrCast(*const [1]u16, a.constSlice().ptr);
|
||||
// try testing.expectEqual(@as(u16, 65535), b[0]);
|
||||
/// ```
|
||||
pub fn BoundedArrayAligned(
|
||||
comptime T: type,
|
||||
comptime alignment: u29,
|
||||
comptime buffer_capacity: usize,
|
||||
) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
buffer: [buffer_capacity]T = undefined,
|
||||
buffer: [buffer_capacity]T align(alignment) = undefined,
|
||||
len: usize = 0,
|
||||
|
||||
/// Set the actual length of the slice.
|
||||
@ -30,15 +51,15 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
||||
|
||||
/// View the internal array as a slice whose size was previously set.
|
||||
pub fn slice(self: anytype) switch (@TypeOf(&self.buffer)) {
|
||||
*[buffer_capacity]T => []T,
|
||||
*const [buffer_capacity]T => []const T,
|
||||
*align(alignment) [buffer_capacity]T => []align(alignment) T,
|
||||
*align(alignment) const [buffer_capacity]T => []align(alignment) const T,
|
||||
else => unreachable,
|
||||
} {
|
||||
return self.buffer[0..self.len];
|
||||
}
|
||||
|
||||
/// View the internal array as a constant slice whose size was previously set.
|
||||
pub fn constSlice(self: *const Self) []const T {
|
||||
pub fn constSlice(self: *const Self) []align(alignment) const T {
|
||||
return self.slice();
|
||||
}
|
||||
|
||||
@ -94,7 +115,7 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
||||
|
||||
/// Resize the slice, adding `n` new elements, which have `undefined` values.
|
||||
/// The return value is a slice pointing to the uninitialized elements.
|
||||
pub fn addManyAsArray(self: *Self, comptime n: usize) error{Overflow}!*[n]T {
|
||||
pub fn addManyAsArray(self: *Self, comptime n: usize) error{Overflow}!*align(alignment) [n]T {
|
||||
const prev_len = self.len;
|
||||
try self.resize(self.len + n);
|
||||
return self.slice()[prev_len..][0..n];
|
||||
@ -118,7 +139,7 @@ pub fn BoundedArray(comptime T: type, comptime buffer_capacity: usize) type {
|
||||
/// This can be useful for writing directly into it.
|
||||
/// Note that such an operation must be followed up with a
|
||||
/// call to `resize()`
|
||||
pub fn unusedCapacitySlice(self: *Self) []T {
|
||||
pub fn unusedCapacitySlice(self: *Self) []align(alignment) T {
|
||||
return self.buffer[self.len..];
|
||||
}
|
||||
|
||||
@ -365,3 +386,15 @@ test "BoundedArray" {
|
||||
try w.writeAll(s);
|
||||
try testing.expectEqualStrings(s, a.constSlice());
|
||||
}
|
||||
|
||||
test "BoundedArrayAligned" {
|
||||
var a = try BoundedArrayAligned(u8, 16, 4).init(0);
|
||||
try a.append(0);
|
||||
try a.append(0);
|
||||
try a.append(255);
|
||||
try a.append(255);
|
||||
|
||||
const b = @ptrCast(*const [2]u16, a.constSlice().ptr);
|
||||
try testing.expectEqual(@as(u16, 0), b[0]);
|
||||
try testing.expectEqual(@as(u16, 65535), b[1]);
|
||||
}
|
||||
|
||||
@ -215,6 +215,10 @@ pub const NamedGroup = enum(u16) {
|
||||
ffdhe6144 = 0x0103,
|
||||
ffdhe8192 = 0x0104,
|
||||
|
||||
// Hybrid post-quantum key agreements
|
||||
x25519_kyber512d00 = 0xFE30,
|
||||
x25519_kyber768d00 = 0xFE31,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
|
||||
@ -158,6 +158,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
|
||||
// Only possible to happen if the private key is all zeroes.
|
||||
error.IdentityElement => return error.InsufficientEntropy,
|
||||
};
|
||||
const kyber768_kp = crypto.kem.kyber_d00.Kyber768.KeyPair.create(null) catch {};
|
||||
|
||||
const extensions_payload =
|
||||
tls.extension(.supported_versions, [_]u8{
|
||||
@ -175,6 +176,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
|
||||
.rsa_pkcs1_sha512,
|
||||
.ed25519,
|
||||
})) ++ tls.extension(.supported_groups, enum_array(tls.NamedGroup, &.{
|
||||
.x25519_kyber768d00,
|
||||
.secp256r1,
|
||||
.x25519,
|
||||
})) ++ tls.extension(
|
||||
@ -182,7 +184,9 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
|
||||
array(1, int2(@enumToInt(tls.NamedGroup.x25519)) ++
|
||||
array(1, x25519_kp.public_key) ++
|
||||
int2(@enumToInt(tls.NamedGroup.secp256r1)) ++
|
||||
array(1, secp256r1_kp.public_key.toUncompressedSec1())),
|
||||
array(1, secp256r1_kp.public_key.toUncompressedSec1()) ++
|
||||
int2(@enumToInt(tls.NamedGroup.x25519_kyber768d00)) ++
|
||||
array(1, x25519_kp.public_key ++ kyber768_kp.public_key.toBytes())),
|
||||
) ++
|
||||
int2(@enumToInt(tls.ExtensionType.server_name)) ++
|
||||
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
|
||||
const extensions_size = hsd.decode(u16);
|
||||
var all_extd = try hsd.sub(extensions_size);
|
||||
var supported_version: u16 = 0;
|
||||
var shared_key: [32]u8 = undefined;
|
||||
var shared_key: []const u8 = undefined;
|
||||
var have_shared_key = false;
|
||||
while (!all_extd.eof()) {
|
||||
try all_extd.ensure(2 + 2);
|
||||
@ -295,14 +299,29 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
|
||||
const key_size = extd.decode(u16);
|
||||
try extd.ensure(key_size);
|
||||
switch (named_group) {
|
||||
.x25519 => {
|
||||
if (key_size != 32) return error.TlsIllegalParameter;
|
||||
const server_pub_key = extd.array(32);
|
||||
.x25519_kyber768d00 => {
|
||||
const xksl = crypto.dh.X25519.public_length;
|
||||
const hksl = xksl + crypto.kem.kyber_d00.Kyber768.ciphertext_length;
|
||||
if (key_size != hksl)
|
||||
return error.TlsIllegalParameter;
|
||||
const server_ks = extd.array(hksl);
|
||||
|
||||
shared_key = crypto.dh.X25519.scalarmult(
|
||||
shared_key = &((crypto.dh.X25519.scalarmult(
|
||||
x25519_kp.secret_key,
|
||||
server_ks[0..xksl].*,
|
||||
) catch return error.TlsDecryptFailure) ++ (kyber768_kp.secret_key.decaps(
|
||||
server_ks[xksl..hksl],
|
||||
) catch return error.TlsDecryptFailure));
|
||||
},
|
||||
.x25519 => {
|
||||
const ksl = crypto.dh.X25519.public_length;
|
||||
if (key_size != ksl) return error.TlsIllegalParameter;
|
||||
const server_pub_key = extd.array(ksl);
|
||||
|
||||
shared_key = &(crypto.dh.X25519.scalarmult(
|
||||
x25519_kp.secret_key,
|
||||
server_pub_key.*,
|
||||
) catch return error.TlsDecryptFailure;
|
||||
) catch return error.TlsDecryptFailure);
|
||||
},
|
||||
.secp256r1 => {
|
||||
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
|
||||
const mul = pk.p.mulPublic(secp256r1_kp.secret_key.bytes, .Big) catch {
|
||||
return error.TlsDecryptFailure;
|
||||
};
|
||||
shared_key = mul.affineCoordinates().x.toBytes(.Big);
|
||||
shared_key = &mul.affineCoordinates().x.toBytes(.Big);
|
||||
},
|
||||
else => {
|
||||
return error.TlsIllegalParameter;
|
||||
@ -358,7 +377,7 @@ pub fn init(stream: anytype, ca_bundle: Certificate.Bundle, host: []const u8) In
|
||||
const early_secret = P.Hkdf.extract(&[1]u8{0}, &zeroes);
|
||||
const empty_hash = tls.emptyHash(P.Hash);
|
||||
const hs_derived_secret = hkdfExpandLabel(P.Hkdf, early_secret, "derived", &empty_hash, P.Hash.digest_length);
|
||||
p.handshake_secret = P.Hkdf.extract(&hs_derived_secret, &shared_key);
|
||||
p.handshake_secret = P.Hkdf.extract(&hs_derived_secret, shared_key);
|
||||
const ap_derived_secret = hkdfExpandLabel(P.Hkdf, p.handshake_secret, "derived", &empty_hash, P.Hash.digest_length);
|
||||
p.master_secret = P.Hkdf.extract(&ap_derived_secret, &zeroes);
|
||||
const client_secret = hkdfExpandLabel(P.Hkdf, p.handshake_secret, "c hs traffic", &hello_hash, P.Hash.digest_length);
|
||||
|
||||
@ -741,7 +741,7 @@ pub fn tcpConnectToAddress(address: Address) TcpConnectToAddressError!Stream {
|
||||
return Stream{ .handle = sockfd };
|
||||
}
|
||||
|
||||
const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || error{
|
||||
const GetAddressListError = std.mem.Allocator.Error || std.fs.File.OpenError || std.fs.File.ReadError || std.os.SocketError || std.os.BindError || std.os.SetSockOptError || error{
|
||||
// TODO: break this up into error sets from the various underlying functions
|
||||
|
||||
TemporaryNameServerFailure,
|
||||
@ -1534,15 +1534,10 @@ fn resMSendRc(
|
||||
ns[i] = iplit.addr;
|
||||
assert(ns[i].getPort() == 53);
|
||||
if (iplit.addr.any.family != os.AF.INET) {
|
||||
sl = @sizeOf(os.sockaddr.in6);
|
||||
family = os.AF.INET6;
|
||||
}
|
||||
}
|
||||
|
||||
// Get local address and open/bind a socket
|
||||
var sa: Address = undefined;
|
||||
@memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
|
||||
sa.any.family = family;
|
||||
const flags = os.SOCK.DGRAM | os.SOCK.CLOEXEC | os.SOCK.NONBLOCK;
|
||||
const fd = os.socket(family, flags, 0) catch |err| switch (err) {
|
||||
error.AddressFamilyNotSupported => blk: {
|
||||
@ -1556,27 +1551,35 @@ fn resMSendRc(
|
||||
else => |e| return e,
|
||||
};
|
||||
defer os.closeSocket(fd);
|
||||
try os.bind(fd, &sa.any, sl);
|
||||
|
||||
// Past this point, there are no errors. Each individual query will
|
||||
// yield either no reply (indicated by zero length) or an answer
|
||||
// packet which is up to the caller to interpret.
|
||||
|
||||
// Convert any IPv4 addresses in a mixed environment to v4-mapped
|
||||
// TODO
|
||||
//if (family == AF.INET6) {
|
||||
// setsockopt(fd, IPPROTO.IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
|
||||
// for (i=0; i<nns; i++) {
|
||||
// if (ns[i].sin.sin_family != AF.INET) continue;
|
||||
// memcpy(ns[i].sin6.sin6_addr.s6_addr+12,
|
||||
// &ns[i].sin.sin_addr, 4);
|
||||
// memcpy(ns[i].sin6.sin6_addr.s6_addr,
|
||||
// "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
|
||||
// ns[i].sin6.sin6_family = AF.INET6;
|
||||
// ns[i].sin6.sin6_flowinfo = 0;
|
||||
// ns[i].sin6.sin6_scope_id = 0;
|
||||
// }
|
||||
//}
|
||||
if (family == os.AF.INET6) {
|
||||
try os.setsockopt(
|
||||
fd,
|
||||
os.SOL.IPV6,
|
||||
os.linux.IPV6.V6ONLY,
|
||||
&mem.toBytes(@as(c_int, 0)),
|
||||
);
|
||||
for (0..ns.len) |i| {
|
||||
if (ns[i].any.family != os.AF.INET) continue;
|
||||
mem.writeIntNative(u32, ns[i].in6.sa.addr[12..], ns[i].in.sa.addr);
|
||||
mem.copy(u8, ns[i].in6.sa.addr[0..12], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff");
|
||||
ns[i].any.family = os.AF.INET6;
|
||||
ns[i].in6.sa.flowinfo = 0;
|
||||
ns[i].in6.sa.scope_id = 0;
|
||||
}
|
||||
sl = @sizeOf(os.sockaddr.in6);
|
||||
}
|
||||
|
||||
// Get local address and open/bind a socket
|
||||
var sa: Address = undefined;
|
||||
@memset(@ptrCast([*]u8, &sa), 0, @sizeOf(Address));
|
||||
sa.any.family = family;
|
||||
try os.bind(fd, &sa.any, sl);
|
||||
|
||||
var pfd = [1]os.pollfd{os.pollfd{
|
||||
.fd = fd,
|
||||
|
||||
@ -9,6 +9,7 @@ pub const AutoArrayHashMapUnmanaged = array_hash_map.AutoArrayHashMapUnmanaged;
|
||||
pub const AutoHashMap = hash_map.AutoHashMap;
|
||||
pub const AutoHashMapUnmanaged = hash_map.AutoHashMapUnmanaged;
|
||||
pub const BoundedArray = @import("bounded_array.zig").BoundedArray;
|
||||
pub const BoundedArrayAligned = @import("bounded_array.zig").BoundedArrayAligned;
|
||||
pub const Build = @import("Build.zig");
|
||||
pub const BufMap = @import("buf_map.zig").BufMap;
|
||||
pub const BufSet = @import("buf_set.zig").BufSet;
|
||||
|
||||
@ -86,7 +86,8 @@ clang_preprocessor_mode: ClangPreprocessorMode,
|
||||
/// Whether to print clang argvs to stdout.
|
||||
verbose_cc: bool,
|
||||
verbose_air: bool,
|
||||
verbose_llvm_ir: bool,
|
||||
verbose_llvm_ir: ?[]const u8,
|
||||
verbose_llvm_bc: ?[]const u8,
|
||||
verbose_cimport: bool,
|
||||
verbose_llvm_cpu_features: bool,
|
||||
disable_c_depfile: bool,
|
||||
@ -585,7 +586,8 @@ pub const InitOptions = struct {
|
||||
verbose_cc: bool = false,
|
||||
verbose_link: bool = false,
|
||||
verbose_air: bool = false,
|
||||
verbose_llvm_ir: bool = false,
|
||||
verbose_llvm_ir: ?[]const u8 = null,
|
||||
verbose_llvm_bc: ?[]const u8 = null,
|
||||
verbose_cimport: bool = false,
|
||||
verbose_llvm_cpu_features: bool = false,
|
||||
is_test: bool = false,
|
||||
@ -1559,6 +1561,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
|
||||
.verbose_cc = options.verbose_cc,
|
||||
.verbose_air = options.verbose_air,
|
||||
.verbose_llvm_ir = options.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = options.verbose_llvm_bc,
|
||||
.verbose_cimport = options.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = options.verbose_llvm_cpu_features,
|
||||
.disable_c_depfile = options.disable_c_depfile,
|
||||
@ -5349,6 +5352,7 @@ fn buildOutputFromZig(
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
@ -5426,6 +5430,7 @@ pub fn build_crt_file(
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
|
||||
@ -4263,7 +4263,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void {
|
||||
comp.emit_llvm_bc == null);
|
||||
|
||||
const dump_air = builtin.mode == .Debug and comp.verbose_air;
|
||||
const dump_llvm_ir = builtin.mode == .Debug and comp.verbose_llvm_ir;
|
||||
const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
|
||||
|
||||
if (no_bin_file and !dump_air and !dump_llvm_ir) return;
|
||||
|
||||
@ -6395,7 +6395,7 @@ pub fn linkerUpdateDecl(mod: *Module, decl_index: Decl.Index) !void {
|
||||
comp.emit_llvm_ir == null and
|
||||
comp.emit_llvm_bc == null);
|
||||
|
||||
const dump_llvm_ir = builtin.mode == .Debug and comp.verbose_llvm_ir;
|
||||
const dump_llvm_ir = builtin.mode == .Debug and (comp.verbose_llvm_ir != null or comp.verbose_llvm_bc != null);
|
||||
|
||||
if (no_bin_file and !dump_llvm_ir) return;
|
||||
|
||||
|
||||
15
src/Sema.zig
15
src/Sema.zig
@ -4712,6 +4712,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
|
||||
.Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}),
|
||||
}
|
||||
|
||||
if ((try sema.typeHasOnePossibleValue(operand_ty.childType())) != null) {
|
||||
// No need to validate the actual pointer value, we don't need it!
|
||||
return;
|
||||
}
|
||||
|
||||
const elem_ty = operand_ty.elemType2();
|
||||
if (try sema.resolveMaybeUndefVal(operand)) |val| {
|
||||
if (val.isUndef()) {
|
||||
@ -15449,9 +15454,13 @@ fn zirRetAddr(
|
||||
block: *Block,
|
||||
extended: Zir.Inst.Extended.InstData,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const src = LazySrcLoc.nodeOffset(@bitCast(i32, extended.operand));
|
||||
try sema.requireRuntimeBlock(block, src, null);
|
||||
return try block.addNoOp(.ret_addr);
|
||||
_ = extended;
|
||||
if (block.is_comptime) {
|
||||
// TODO: we could give a meaningful lazy value here. #14938
|
||||
return sema.addIntUnsigned(Type.usize, 0);
|
||||
} else {
|
||||
return block.addNoOp(.ret_addr);
|
||||
}
|
||||
}
|
||||
|
||||
fn zirFrameAddress(
|
||||
|
||||
@ -756,8 +756,35 @@ pub const Object = struct {
|
||||
dib.finalize();
|
||||
}
|
||||
|
||||
if (comp.verbose_llvm_ir) {
|
||||
self.llvm_module.dump();
|
||||
if (comp.verbose_llvm_ir) |path| {
|
||||
if (std.mem.eql(u8, path, "-")) {
|
||||
self.llvm_module.dump();
|
||||
} else {
|
||||
const path_z = try comp.gpa.dupeZ(u8, path);
|
||||
defer comp.gpa.free(path_z);
|
||||
|
||||
var error_message: [*:0]const u8 = undefined;
|
||||
|
||||
if (self.llvm_module.printModuleToFile(path_z, &error_message).toBool()) {
|
||||
defer llvm.disposeMessage(error_message);
|
||||
|
||||
log.err("dump LLVM module failed ir={s}: {s}", .{
|
||||
path, error_message,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (comp.verbose_llvm_bc) |path| {
|
||||
const path_z = try comp.gpa.dupeZ(u8, path);
|
||||
defer comp.gpa.free(path_z);
|
||||
|
||||
const error_code = self.llvm_module.writeBitcodeToFile(path_z);
|
||||
if (error_code != 0) {
|
||||
log.err("dump LLVM module failed bc={s}: {d}", .{
|
||||
path, error_code,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var arena_allocator = std.heap.ArenaAllocator.init(comp.gpa);
|
||||
|
||||
@ -422,6 +422,9 @@ pub const Module = opaque {
|
||||
|
||||
pub const printModuleToFile = LLVMPrintModuleToFile;
|
||||
extern fn LLVMPrintModuleToFile(M: *Module, Filename: [*:0]const u8, ErrorMessage: *[*:0]const u8) Bool;
|
||||
|
||||
pub const writeBitcodeToFile = LLVMWriteBitcodeToFile;
|
||||
extern fn LLVMWriteBitcodeToFile(M: *Module, Path: [*:0]const u8) c_int;
|
||||
};
|
||||
|
||||
pub const lookupIntrinsicID = LLVMLookupIntrinsicID;
|
||||
|
||||
@ -1097,6 +1097,7 @@ fn buildSharedLib(
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
|
||||
@ -250,6 +250,7 @@ pub fn buildLibCXX(comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
@ -410,6 +411,7 @@ pub fn buildLibCXXABI(comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
|
||||
@ -226,6 +226,7 @@ pub fn buildTsan(comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
|
||||
@ -122,6 +122,7 @@ pub fn buildStaticLib(comp: *Compilation, prog_node: *std.Progress.Node) !void {
|
||||
.verbose_link = comp.bin_file.options.verbose_link,
|
||||
.verbose_air = comp.verbose_air,
|
||||
.verbose_llvm_ir = comp.verbose_llvm_ir,
|
||||
.verbose_llvm_bc = comp.verbose_llvm_bc,
|
||||
.verbose_cimport = comp.verbose_cimport,
|
||||
.verbose_llvm_cpu_features = comp.verbose_llvm_cpu_features,
|
||||
.clang_passthrough_mode = comp.clang_passthrough_mode,
|
||||
|
||||
23
src/main.zig
23
src/main.zig
@ -370,10 +370,10 @@ const usage_build_generic =
|
||||
\\ -fno-emit-bin Do not output machine code
|
||||
\\ -femit-asm[=path] Output .s (assembly code)
|
||||
\\ -fno-emit-asm (default) Do not output .s (assembly code)
|
||||
\\ -femit-llvm-ir[=path] Produce a .ll file with LLVM IR (requires LLVM extensions)
|
||||
\\ -fno-emit-llvm-ir (default) Do not produce a .ll file with LLVM IR
|
||||
\\ -femit-llvm-bc[=path] Produce a LLVM module as a .bc file (requires LLVM extensions)
|
||||
\\ -fno-emit-llvm-bc (default) Do not produce a LLVM module as a .bc file
|
||||
\\ -femit-llvm-ir[=path] Produce a .ll file with optimized LLVM IR (requires LLVM extensions)
|
||||
\\ -fno-emit-llvm-ir (default) Do not produce a .ll file with optimized LLVM IR
|
||||
\\ -femit-llvm-bc[=path] Produce an optimized LLVM module as a .bc file (requires LLVM extensions)
|
||||
\\ -fno-emit-llvm-bc (default) Do not produce an optimized LLVM module as a .bc file
|
||||
\\ -femit-h[=path] Generate a C header file (.h)
|
||||
\\ -fno-emit-h (default) Do not generate a C header file (.h)
|
||||
\\ -femit-docs[=path] Create a docs/ dir with html documentation
|
||||
@ -555,13 +555,14 @@ const usage_build_generic =
|
||||
\\ --test-runner [path] Specify a custom test runner
|
||||
\\
|
||||
\\Debug Options (Zig Compiler Development):
|
||||
\\ -fopt-bisect-limit [limit] Only run [limit] first LLVM optimization passes
|
||||
\\ -fopt-bisect-limit=[limit] Only run [limit] first LLVM optimization passes
|
||||
\\ -ftime-report Print timing diagnostics
|
||||
\\ -fstack-report Print stack size diagnostics
|
||||
\\ --verbose-link Display linker invocations
|
||||
\\ --verbose-cc Display C compiler invocations
|
||||
\\ --verbose-air Enable compiler debug output for Zig AIR
|
||||
\\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
|
||||
\\ --verbose-llvm-ir[=path] Enable compiler debug output for unoptimized LLVM IR
|
||||
\\ --verbose-llvm-bc=[path] Enable compiler debug output for unoptimized LLVM BC
|
||||
\\ --verbose-cimport Enable compiler debug output for C imports
|
||||
\\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
|
||||
\\ --debug-log [scope] Enable printing debug/info log messages for scope
|
||||
@ -704,7 +705,8 @@ fn buildOutputType(
|
||||
var verbose_link = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_LINK");
|
||||
var verbose_cc = (builtin.os.tag != .wasi or builtin.link_libc) and std.process.hasEnvVarConstant("ZIG_VERBOSE_CC");
|
||||
var verbose_air = false;
|
||||
var verbose_llvm_ir = false;
|
||||
var verbose_llvm_ir: ?[]const u8 = null;
|
||||
var verbose_llvm_bc: ?[]const u8 = null;
|
||||
var verbose_cimport = false;
|
||||
var verbose_llvm_cpu_features = false;
|
||||
var time_report = false;
|
||||
@ -1441,7 +1443,11 @@ fn buildOutputType(
|
||||
} else if (mem.eql(u8, arg, "--verbose-air")) {
|
||||
verbose_air = true;
|
||||
} else if (mem.eql(u8, arg, "--verbose-llvm-ir")) {
|
||||
verbose_llvm_ir = true;
|
||||
verbose_llvm_ir = "-";
|
||||
} else if (mem.startsWith(u8, arg, "--verbose-llvm-ir=")) {
|
||||
verbose_llvm_ir = arg["--verbose-llvm-ir=".len..];
|
||||
} else if (mem.startsWith(u8, arg, "--verbose-llvm-bc=")) {
|
||||
verbose_llvm_bc = arg["--verbose-llvm-bc=".len..];
|
||||
} else if (mem.eql(u8, arg, "--verbose-cimport")) {
|
||||
verbose_cimport = true;
|
||||
} else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
|
||||
@ -3226,6 +3232,7 @@ fn buildOutputType(
|
||||
.verbose_link = verbose_link,
|
||||
.verbose_air = verbose_air,
|
||||
.verbose_llvm_ir = verbose_llvm_ir,
|
||||
.verbose_llvm_bc = verbose_llvm_bc,
|
||||
.verbose_cimport = verbose_cimport,
|
||||
.verbose_llvm_cpu_features = verbose_llvm_cpu_features,
|
||||
.machine_code_model = machine_code_model,
|
||||
|
||||
@ -191,6 +191,7 @@ test {
|
||||
_ = @import("behavior/pub_enum.zig");
|
||||
_ = @import("behavior/ref_var_in_if_after_if_2nd_switch_prong.zig");
|
||||
_ = @import("behavior/reflection.zig");
|
||||
_ = @import("behavior/return_address.zig");
|
||||
_ = @import("behavior/saturating_arithmetic.zig");
|
||||
_ = @import("behavior/select.zig");
|
||||
_ = @import("behavior/shuffle.zig");
|
||||
|
||||
@ -420,3 +420,11 @@ test "mutate entire slice at comptime" {
|
||||
buf[1..3].* = x;
|
||||
}
|
||||
}
|
||||
|
||||
test "dereference undefined pointer to zero-bit type" {
|
||||
const p0: *void = undefined;
|
||||
try testing.expectEqual({}, p0.*);
|
||||
|
||||
const p1: *[0]u32 = undefined;
|
||||
try testing.expect(p1.*.len == 0);
|
||||
}
|
||||
|
||||
17
test/behavior/return_address.zig
Normal file
17
test/behavior/return_address.zig
Normal file
@ -0,0 +1,17 @@
|
||||
const builtin = @import("builtin");
|
||||
const testing = @import("std").testing;
|
||||
|
||||
fn retAddr() usize {
|
||||
return @returnAddress();
|
||||
}
|
||||
|
||||
test "return address" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||
_ = retAddr();
|
||||
// TODO: #14938
|
||||
try testing.expectEqual(0, comptime retAddr());
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user