From 21932a0ef25a7055cd3c0850fa58c2fda2ba383b Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 5 Feb 2020 20:31:18 +0100 Subject: [PATCH 1/3] Fix edge case in cast between fn with varargs * Prevent the next_param_index to become greater than the param_count one as it's expected by every other function. * Fix a typo in a error message. Closes #4381 --- src/ir.cpp | 4 ++-- src/parser.cpp | 2 +- test/compile_errors.zig | 11 +++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index ef3426d111f8e111b4878706dd8b631a7bed1cb3..0687d18ef2f12f7c47ed3b99e05836b949c14ad1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11864,7 +11864,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted } assert(wanted_type->data.fn.is_generic || wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); - for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) { + for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.param_count; i += 1) { // note it's reversed for parameters FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; @@ -30285,7 +30285,7 @@ static ZigType *ir_resolve_lazy_fn_type(IrAnalyze *ira, AstNode *source_node, La if (param_is_var_args) { if (fn_type_id.cc == CallingConventionC) { fn_type_id.param_count = fn_type_id.next_param_index; - continue; + break; } else if (fn_type_id.cc == CallingConventionUnspecified) { return get_generic_fn_type(ira->codegen, &fn_type_id); } else { diff --git a/src/parser.cpp b/src/parser.cpp index a4dc324b2fe26da94c7a75933d8207cb5a2a1a68..0da7aac6399bd688aa1d647773d236c72c158be0 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -806,7 +806,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) { if (param_decl->data.param_decl.is_var_args) res->data.fn_proto.is_var_args = true; if (i != params.length - 1 && res->data.fn_proto.is_var_args) - ast_error(pc, first, "Function prototype have varargs as a none last paramter."); + ast_error(pc, first, "Function prototype have varargs as a none last parameter."); } return res; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 341062e161f5d26dfbc04c76e3e4bf43caef0c0d..0af07d3ecebfbfa778fb336e1ac03faa177ec5c9 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -3,6 +3,17 @@ const builtin = @import("builtin"); const Target = @import("std").Target; pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.addTest("type mismatch in C prototype with varargs", + \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void; + \\extern fn fn_decl(fmt: [*:0]u8, ...) void; + \\ + \\export fn main() void { + \\ const x: fn_ty = fn_decl; + \\} + , &[_][]const u8{ + "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'", + }); + cases.addTest("dependency loop in top-level decl with @TypeInfo", \\export const foo = @typeInfo(@This()); , &[_][]const u8{ -- 2.54.0 From 9d41ff335ca8f5f635a3b192339f637192bd73c8 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 5 Feb 2020 20:37:00 +0100 Subject: [PATCH 2/3] std: Make TCSA enum ABI-compliant --- lib/std/os/bits/linux.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig index e0fc5561f28072e32a30af2bfa4e1e2a2ea95e21..8077d4b16a787ee6b2831c49999581594452b37e 100644 --- a/lib/std/os/bits/linux.zig +++ b/lib/std/os/bits/linux.zig @@ -1572,7 +1572,7 @@ pub const NOFLSH = 128; pub const TOSTOP = 256; pub const IEXTEN = 32768; -pub const TCSA = extern enum(usize) { +pub const TCSA = extern enum(c_uint) { NOW, DRAIN, FLUSH, -- 2.54.0 From 8c55c4550a7f79d732f0d2ffbf0455b058ab5aad Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 5 Feb 2020 20:39:14 +0100 Subject: [PATCH 3/3] std: Rename isAbsoluteW to isAbsoluteWindowsW --- lib/std/fs.zig | 10 +++++----- lib/std/fs/path.zig | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/std/fs.zig b/lib/std/fs.zig index fe59b6ee2ecf85c7c2969665e488dd70dad72d7c..ec351ff6e22e946fe578a30b42bce0d2b18a0190 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -810,7 +810,7 @@ pub const Dir = struct { }; var attr = w.OBJECT_ATTRIBUTES{ .Length = @sizeOf(w.OBJECT_ATTRIBUTES), - .RootDirectory = if (path.isAbsoluteW(sub_path_w)) null else self.fd, + .RootDirectory = if (path.isAbsoluteWindowsW(sub_path_w)) null else self.fd, .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here. .ObjectName = &nt_name, .SecurityDescriptor = null, @@ -960,7 +960,7 @@ pub const Dir = struct { }; var attr = w.OBJECT_ATTRIBUTES{ .Length = @sizeOf(w.OBJECT_ATTRIBUTES), - .RootDirectory = if (path.isAbsoluteW(sub_path_w)) null else self.fd, + .RootDirectory = if (path.isAbsoluteWindowsW(sub_path_w)) null else self.fd, .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here. .ObjectName = &nt_name, .SecurityDescriptor = null, @@ -1327,7 +1327,7 @@ pub fn openFileAbsoluteC(absolute_path_c: [*:0]const u8, flags: File.OpenFlags) /// Same as `openFileAbsolute` but the path parameter is WTF-16 encoded. pub fn openFileAbsoluteW(absolute_path_w: [*:0]const u16, flags: File.OpenFlags) File.OpenError!File { - assert(path.isAbsoluteW(absolute_path_w)); + assert(path.isAbsoluteWindowsW(absolute_path_w)); return cwd().openFileW(absolute_path_w, flags); } @@ -1350,7 +1350,7 @@ pub fn createFileAbsoluteC(absolute_path_c: [*:0]const u8, flags: File.CreateFla /// Same as `createFileAbsolute` but the path parameter is WTF-16 encoded. pub fn createFileAbsoluteW(absolute_path_w: [*:0]const u16, flags: File.CreateFlags) File.OpenError!File { - assert(path.isAbsoluteW(absolute_path_w)); + assert(path.isAbsoluteWindowsW(absolute_path_w)); return cwd().createFileW(absolute_path_w, flags); } @@ -1371,7 +1371,7 @@ pub fn deleteFileAbsoluteC(absolute_path_c: [*:0]const u8) DeleteFileError!void /// Same as `deleteFileAbsolute` except the parameter is WTF-16 encoded. pub fn deleteFileAbsoluteW(absolute_path_w: [*:0]const u16) DeleteFileError!void { - assert(path.isAbsoluteW(absolute_path_w)); + assert(path.isAbsoluteWindowsW(absolute_path_w)); return cwd().deleteFileW(absolute_path_w); } diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index 2286df047006f8e7e4668add174a68cc3ed81b02..f6f34585bebbdadedd248b44f80a3b4324b4228e 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -173,7 +173,7 @@ pub fn isAbsoluteWindows(path: []const u8) bool { return isAbsoluteWindowsImpl(u8, path); } -pub fn isAbsoluteW(path_w: [*:0]const u16) bool { +pub fn isAbsoluteWindowsW(path_w: [*:0]const u16) bool { return isAbsoluteWindowsImpl(u16, mem.toSliceConst(u16, path_w)); } -- 2.54.0