diff --git a/ci/srht/on_master_success b/ci/srht/on_master_success index 4c28d2af38..691c18a054 100755 --- a/ci/srht/on_master_success +++ b/ci/srht/on_master_success @@ -23,7 +23,7 @@ packages: - jq - xz secrets: - - 6c60aaee-92e7-4e7d-812c-114817689b4d + - 51bfddf5-86a6-4e01-8576-358c72a4a0a4 sources: - https://github.com/ziglang/zig tasks: diff --git a/lib/std/elf.zig b/lib/std/elf.zig index cd2b5fcd06..9f56721214 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -471,7 +471,7 @@ pub const SectionHeaderIterator = struct { if (self.elf_header.is_64) { var shdr: Elf64_Shdr = undefined; - const offset = self.elf_header.phoff + @sizeOf(@TypeOf(shdr)) * self.index; + const offset = self.elf_header.shoff + @sizeOf(@TypeOf(shdr)) * self.index; try preadNoEof(self.file, mem.asBytes(&shdr), offset); // ELF endianness matches native endianness. diff --git a/lib/std/meta.zig b/lib/std/meta.zig index b27f168ac9..1507aa9de8 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -717,7 +717,7 @@ pub fn cast(comptime DestType: type, target: anytype) DestType { }, .Optional => |opt| { if (@typeInfo(opt.child) == .Pointer) { - return @ptrCast(DestType, @alignCast(dest_ptr, target)); + return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target)); } }, else => {}, @@ -725,23 +725,24 @@ pub fn cast(comptime DestType: type, target: anytype) DestType { }, .Optional => |dest_opt| { if (@typeInfo(dest_opt.child) == .Pointer) { + const dest_ptr = @typeInfo(dest_opt.child).Pointer; switch (@typeInfo(TargetType)) { .Int, .ComptimeInt => { return @intToPtr(DestType, target); }, .Pointer => { - return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target)); + return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target)); }, .Optional => |target_opt| { if (@typeInfo(target_opt.child) == .Pointer) { - return @ptrCast(DestType, @alignCast(@alignOf(dest_opt.child.Child), target)); + return @ptrCast(DestType, @alignCast(dest_ptr.alignment, target)); } }, else => {}, } } }, - .Enum, .EnumLiteral => { + .Enum => { if (@typeInfo(TargetType) == .Int or @typeInfo(TargetType) == .ComptimeInt) { return @intToEnum(DestType, target); } @@ -749,15 +750,18 @@ pub fn cast(comptime DestType: type, target: anytype) DestType { .Int, .ComptimeInt => { switch (@typeInfo(TargetType)) { .Pointer => { - return @as(DestType, @ptrToInt(target)); + return @intCast(DestType, @ptrToInt(target)); }, .Optional => |opt| { if (@typeInfo(opt.child) == .Pointer) { - return @as(DestType, @ptrToInt(target)); + return @intCast(DestType, @ptrToInt(target)); } }, - .Enum, .EnumLiteral => { - return @as(DestType, @enumToInt(target)); + .Enum => { + return @intCast(DestType, @enumToInt(target)); + }, + .Int, .ComptimeInt => { + return @intCast(DestType, target); }, else => {}, } @@ -776,10 +780,49 @@ test "std.meta.cast" { var i = @as(i64, 10); - testing.expect(cast(?*c_void, 0) == @intToPtr(?*c_void, 0)); testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16)); - testing.expect(cast(u64, @as(u32, 10)) == @as(u64, 10)); - testing.expect(cast(E, 1) == .One); - testing.expect(cast(u8, E.Two) == 2); testing.expect(cast(*u64, &i).* == @as(u64, 10)); + testing.expect(cast(*i64, @as(?*align(1) i64, &i)) == &i); + + testing.expect(cast(?*u8, 2) == @intToPtr(*u8, 2)); + testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i); + testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i); + + testing.expect(cast(E, 1) == .One); + + testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4))); + testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4))); + testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10))); + testing.expectEqual(@as(u8, 2), cast(u8, E.Two)); +} + +/// Given a value returns its size as C's sizeof operator would. +/// This is for translate-c and is not intended for general use. +pub fn sizeof(target: anytype) usize { + switch (@typeInfo(@TypeOf(target))) { + .Type => return @sizeOf(target), + .Float, .Int, .Struct, .Union, .Enum => return @sizeOf(@TypeOf(target)), + .ComptimeFloat => return @sizeOf(f64), // TODO c_double #3999 + .ComptimeInt => { + // TODO to get the correct result we have to translate + // `1073741824 * 4` as `int(1073741824) *% int(4)` since + // sizeof(1073741824 * 4) != sizeof(4294967296). + + // TODO test if target fits in int, long or long long + return @sizeOf(c_int); + }, + else => @compileError("TODO implement std.meta.sizeof for type " ++ @typeName(@TypeOf(target))), + } +} + +test "sizeof" { + const E = extern enum(c_int) { One, _ }; + const S = extern struct { a: u32 }; + + testing.expect(sizeof(u32) == 4); + testing.expect(sizeof(@as(u32, 2)) == 4); + testing.expect(sizeof(2) == @sizeOf(c_int)); + testing.expect(sizeof(E) == @sizeOf(c_int)); + testing.expect(sizeof(E.One) == @sizeOf(c_int)); + testing.expect(sizeof(S) == 4); } diff --git a/src-self-hosted/libc_installation.zig b/src-self-hosted/libc_installation.zig index 05ac8a8101..535892ce74 100644 --- a/src-self-hosted/libc_installation.zig +++ b/src-self-hosted/libc_installation.zig @@ -10,6 +10,8 @@ const is_darwin = Target.current.isDarwin(); const is_windows = Target.current.os.tag == .windows; const is_gnu = Target.current.isGnu(); +const log = std.log.scoped(.libc_installation); + usingnamespace @import("windows_sdk.zig"); // TODO https://github.com/ziglang/zig/issues/6345 @@ -40,7 +42,6 @@ pub const LibCInstallation = struct { pub fn parse( allocator: *Allocator, libc_file: []const u8, - stderr: anytype, ) !LibCInstallation { var self: LibCInstallation = .{}; @@ -65,7 +66,7 @@ pub const LibCInstallation = struct { if (line.len == 0 or line[0] == '#') continue; var line_it = std.mem.split(line, "="); const name = line_it.next() orelse { - try stderr.print("missing equal sign after field name\n", .{}); + log.err("missing equal sign after field name\n", .{}); return error.ParseError; }; const value = line_it.rest(); @@ -84,31 +85,31 @@ pub const LibCInstallation = struct { } inline for (fields) |field, i| { if (!found_keys[i].found) { - try stderr.print("missing field: {}\n", .{field.name}); + log.err("missing field: {}\n", .{field.name}); return error.ParseError; } } if (self.include_dir == null) { - try stderr.print("include_dir may not be empty\n", .{}); + log.err("include_dir may not be empty\n", .{}); return error.ParseError; } if (self.sys_include_dir == null) { - try stderr.print("sys_include_dir may not be empty\n", .{}); + log.err("sys_include_dir may not be empty\n", .{}); return error.ParseError; } if (self.crt_dir == null and !is_darwin) { - try stderr.print("crt_dir may not be empty for {}\n", .{@tagName(Target.current.os.tag)}); + log.err("crt_dir may not be empty for {}\n", .{@tagName(Target.current.os.tag)}); return error.ParseError; } if (self.msvc_lib_dir == null and is_windows and !is_gnu) { - try stderr.print("msvc_lib_dir may not be empty for {}-{}\n", .{ + log.err("msvc_lib_dir may not be empty for {}-{}\n", .{ @tagName(Target.current.os.tag), @tagName(Target.current.abi), }); return error.ParseError; } if (self.kernel32_lib_dir == null and is_windows and !is_gnu) { - try stderr.print("kernel32_lib_dir may not be empty for {}-{}\n", .{ + log.err("kernel32_lib_dir may not be empty for {}-{}\n", .{ @tagName(Target.current.os.tag), @tagName(Target.current.abi), }); diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index a9a9496b94..623da30e2c 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -615,12 +615,9 @@ const Stage2LibCInstallation = extern struct { // ABI warning export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error { - stderr_file = std.io.getStdErr(); - stderr = stderr_file.outStream(); const libc_file = mem.spanZ(libc_file_z); - var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file, stderr) catch |err| switch (err) { + var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file) catch |err| switch (err) { error.ParseError => return .SemanticAnalyzeFail, - error.DiskQuota => return .DiskQuota, error.FileTooBig => return .FileTooBig, error.InputOutput => return .FileSystem, error.NoSpaceLeft => return .NoSpaceLeft, @@ -629,7 +626,6 @@ export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [ error.SystemResources => return .SystemResources, error.OperationAborted => return .OperationAborted, error.WouldBlock => unreachable, - error.NotOpenForWriting => unreachable, error.NotOpenForReading => unreachable, error.Unexpected => return .Unexpected, error.IsDir => return .IsDir, diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index cd42e8abee..1cdb5099e1 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -6324,10 +6324,18 @@ fn parseCPrefixOpExpr(c: *Context, m: *MacroCtx, scope: *Scope) ParseError!*ast. break :blk inner; } else try parseCPrefixOpExpr(c, m, scope); - const builtin_call = try c.createBuiltinCall("@sizeOf", 1); - builtin_call.params()[0] = inner; - builtin_call.rparen_token = try appendToken(c, .RParen, ")"); - return &builtin_call.base; + //(@import("std").meta.sizeof(dest, x)) + const import_fn_call = try c.createBuiltinCall("@import", 1); + const std_node = try transCreateNodeStringLiteral(c, "\"std\""); + import_fn_call.params()[0] = std_node; + import_fn_call.rparen_token = try appendToken(c, .RParen, ")"); + const inner_field_access = try transCreateNodeFieldAccess(c, &import_fn_call.base, "meta"); + const outer_field_access = try transCreateNodeFieldAccess(c, inner_field_access, "sizeof"); + + const sizeof_call = try c.createCall(outer_field_access, 1); + sizeof_call.params()[0] = inner; + sizeof_call.rtoken = try appendToken(c, .RParen, ")"); + return &sizeof_call.base; }, .Keyword_alignof => { // TODO this won't work if using 's