aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-05-25 13:48:10 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-05-25 13:48:10 -0400
commitfcdd808c5c1b866c2582a17839a53ce7bbbb78d6 (patch)
tree5c8d30ee489a33022ff28d5916d437dd02b5c960 /src/ir.cpp
parent68add5d8286e5c517143b16a457a86a6c23dbc64 (diff)
downloadzig-fcdd808c5c1b866c2582a17839a53ce7bbbb78d6.tar.gz
zig-fcdd808c5c1b866c2582a17839a53ce7bbbb78d6.zip
fix segfault with array of variadic functions
closes #377
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp31
1 files changed, 27 insertions, 4 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 3a22218ee3..b444281918 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -1857,14 +1857,17 @@ static IrInstruction *ir_build_unwrap_err_payload_from(IrBuilder *irb, IrInstruc
}
static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node,
- IrInstruction **param_types, IrInstruction *return_type)
+ IrInstruction **param_types, IrInstruction *return_type, bool is_var_args)
{
IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node);
instruction->param_types = param_types;
instruction->return_type = return_type;
+ instruction->is_var_args = is_var_args;
assert(source_node->type == NodeTypeFnProto);
- for (size_t i = 0; i < source_node->data.fn_proto.params.length; i += 1) {
+ size_t param_count = source_node->data.fn_proto.params.length;
+ if (is_var_args) param_count -= 1;
+ for (size_t i = 0; i < param_count; i += 1) {
ir_ref_instruction(param_types[i], irb->current_basic_block);
}
ir_ref_instruction(return_type, irb->current_basic_block);
@@ -5843,8 +5846,13 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
size_t param_count = node->data.fn_proto.params.length;
IrInstruction **param_types = allocate<IrInstruction*>(param_count);
+ bool is_var_args = false;
for (size_t i = 0; i < param_count; i += 1) {
AstNode *param_node = node->data.fn_proto.params.at(i);
+ if (param_node->data.param_decl.is_var_args) {
+ is_var_args = true;
+ break;
+ }
AstNode *type_node = param_node->data.param_decl.type;
IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope);
if (type_value == irb->codegen->invalid_instruction)
@@ -5856,7 +5864,7 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo
if (return_type == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
- return ir_build_fn_proto(irb, parent_scope, node, param_types, return_type);
+ return ir_build_fn_proto(irb, parent_scope, node, param_types, return_type, is_var_args);
}
static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope,
@@ -9039,7 +9047,11 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
}
if (fn_type->data.fn.is_generic) {
- assert(fn_entry);
+ if (!fn_entry) {
+ ir_add_error(ira, call_instruction->fn_ref,
+ buf_sprintf("calling a generic function requires compile-time known function value"));
+ return ira->codegen->builtin_types.entry_invalid;
+ }
// Count the arguments of the function type id we are creating
size_t new_fn_arg_count = first_arg_1_or_0;
@@ -13065,6 +13077,17 @@ static TypeTableEntry *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruc
AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index);
assert(param_node->type == NodeTypeParamDecl);
+ bool param_is_var_args = param_node->data.param_decl.is_var_args;
+ if (param_is_var_args) {
+ if (fn_type_id.is_extern) {
+ fn_type_id.param_count = fn_type_id.next_param_index;
+ continue;
+ } else {
+ ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
+ out_val->data.x_type = get_generic_fn_type(ira->codegen, &fn_type_id);
+ return ira->codegen->builtin_types.entry_type;
+ }
+ }
IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->other;
FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index];