Commit a3de550d3b

Andrew Kelley <superjoe30@gmail.com>
2017-04-07 03:00:49
fix var args having wrong index when runtime param before it
closes #312
1 parent 273cebd
Changed files (2)
src
test
src/ir.cpp
@@ -8346,7 +8346,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
         }
 
         bool found_first_var_arg = false;
-        size_t first_var_arg = inst_fn_type_id.param_count;
+        size_t first_var_arg;
 
         FnTableEntry *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);
         assert(parent_fn_entry);
@@ -8394,6 +8394,10 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
             AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
             Buf *param_name = param_decl_node->data.param_decl.name;
 
+            if (!found_first_var_arg) {
+                first_var_arg = inst_fn_type_id.param_count;
+            }
+
             ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen,
                     first_var_arg, inst_fn_type_id.param_count);
             VariableTableEntry *var = add_variable(ira->codegen, param_decl_node,
test/cases/var_args.zig
@@ -31,3 +31,25 @@ test "testPassArgsDirectly" {
 fn addSomeStuff(args: ...) -> i32 {
     return add(args);
 }
+
+test "runtime parameter before var args" {
+    assert(extraFn(10) == 0);
+    assert(extraFn(10, false) == 1);
+    assert(extraFn(10, false, true) == 2);
+
+    //comptime {
+    //    assert(extraFn(10) == 0);
+    //    assert(extraFn(10, false) == 1);
+    //    assert(extraFn(10, false, true) == 2);
+    //}
+}
+
+fn extraFn(extra: u32, args: ...) -> usize {
+    if (args.len >= 1) {
+        assert(args[0] == false);
+    }
+    if (args.len >= 2) {
+        assert(args[1] == true);
+    }
+    return args.len;
+}