aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-04-06 21:00:49 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-04-06 21:00:49 -0400
commita3de550d3bf020fd68e1331d3cb8b7b422894f96 (patch)
treef6d5a2a173bc3dd6c42fc0581cc1ec9d06fa3cea
parent273cebdf4dde46f00eb177b9aa05d8dd1c0606a7 (diff)
downloadzig-a3de550d3bf020fd68e1331d3cb8b7b422894f96.tar.gz
zig-a3de550d3bf020fd68e1331d3cb8b7b422894f96.zip
fix var args having wrong index when runtime param before it
closes #312
-rw-r--r--src/ir.cpp6
-rw-r--r--test/cases/var_args.zig22
2 files changed, 27 insertions, 1 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 79f4a27914..c7c9c6490c 100644
--- a/src/ir.cpp
+++ b/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,
diff --git a/test/cases/var_args.zig b/test/cases/var_args.zig
index 0e61a0c567..655eb05195 100644
--- a/test/cases/var_args.zig
+++ b/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;
+}