authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-05 20:31:18+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-05 20:31:18+01:00
log21932a0ef25a7055cd3c0850fa58c2fda2ba383b
treebc154b72c1162381e4d0b560b43e68507b442997
parentb022db16ece48f2cdec47c5716601fec2fc07ef4

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

3 files changed, 14 insertions(+), 3 deletions(-)

src/ir.cpp+2-2
......@@ -11864,7 +11864,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
1186411864 }
1186511865 assert(wanted_type->data.fn.is_generic ||
1186611866 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count);
11867 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) {
11867 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.param_count; i += 1) {
1186811868 // note it's reversed for parameters
1186911869 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i];
1187011870 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
3028530285 if (param_is_var_args) {
3028630286 if (fn_type_id.cc == CallingConventionC) {
3028730287 fn_type_id.param_count = fn_type_id.next_param_index;
30288 continue;
30288 break;
3028930289 } else if (fn_type_id.cc == CallingConventionUnspecified) {
3029030290 return get_generic_fn_type(ira->codegen, &fn_type_id);
3029130291 } else {
src/parser.cpp+1-1
......@@ -806,7 +806,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
806806 if (param_decl->data.param_decl.is_var_args)
807807 res->data.fn_proto.is_var_args = true;
808808 if (i != params.length - 1 && res->data.fn_proto.is_var_args)
809 ast_error(pc, first, "Function prototype have varargs as a none last paramter.");
809 ast_error(pc, first, "Function prototype have varargs as a none last parameter.");
810810 }
811811 return res;
812812}
test/compile_errors.zig+11
......@@ -3,6 +3,17 @@ const builtin = @import("builtin");
33const Target = @import("std").Target;
44
55pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("type mismatch in C prototype with varargs",
7 \\const fn_ty = ?fn ([*c]u8, ...) callconv(.C) void;
8 \\extern fn fn_decl(fmt: [*:0]u8, ...) void;
9 \\
10 \\export fn main() void {
11 \\ const x: fn_ty = fn_decl;
12 \\}
13 , &[_][]const u8{
14 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",
15 });
16
617 cases.addTest("dependency loop in top-level decl with @TypeInfo",
718 \\export const foo = @typeInfo(@This());
819 , &[_][]const u8{