Commit 7ea669e04c

Andrew Kelley <superjoe30@gmail.com>
2017-11-09 17:30:39
fix parameter of extern var args not type checked
closes #601
1 parent 4f8c26d
Changed files (2)
src/ir.cpp
@@ -10311,8 +10311,17 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
 {
     FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
     size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0;
-    size_t var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0;
+
+    // for extern functions, the var args argument is not counted.
+    // for zig functions, it is.
+    size_t var_args_1_or_0;
+    if (fn_type_id->cc == CallingConventionUnspecified) {
+        var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0;
+    } else {
+        var_args_1_or_0 = 0;
+    }
     size_t src_param_count = fn_type_id->param_count - var_args_1_or_0;
+
     size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0;
     AstNode *source_node = call_instruction->base.source_node;
 
test/compile_errors.zig
@@ -2335,4 +2335,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
         \\const Foo = enum {};
     ,
         ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members");
+
+    cases.add("calling var args extern function, passing array instead of pointer",
+        \\export fn entry() {
+        \\    foo("hello");
+        \\}
+        \\pub extern fn foo(format: &const u8, ...);
+    ,
+        ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
 }