authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 17:42:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 17:42:29-07:00
logd0a1901cb06bf9efaa4c78f9a990663aeb63ce85
treef3bc07ef54b3ccb89932eb6d3ff1ccf692cd775c
parent974d69ea3d0db71b97af00e325fdfb421c0906c2

fix function calling of pointers

See #14

2 files changed, 46 insertions(+), 24 deletions(-)

src/analyze.cpp+23-24
...@@ -3593,33 +3593,27 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -3593,33 +3593,27 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
3593 zig_unreachable();3593 zig_unreachable();
3594}3594}
35953595
3596static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, BlockContext *context,3596static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3597 TypeTableEntry *expected_type, AstNode *node, FnTableEntry *fn_table_entry, TypeTableEntry *struct_type)3597 TypeTableEntry *expected_type, AstNode *node, TypeTableEntry *fn_type, TypeTableEntry *struct_type)
3598{3598{
3599 assert(node->type == NodeTypeFnCallExpr);3599 assert(node->type == NodeTypeFnCallExpr);
36003600
3601 node->data.fn_call_expr.fn_entry = fn_table_entry;
3602 assert(fn_table_entry->proto_node->type == NodeTypeFnProto);
3603 AstNodeFnProto *fn_proto = &fn_table_entry->proto_node->data.fn_proto;
3604
3605 // count parameters3601 // count parameters
3606 int expected_param_count = fn_proto->params.length;3602 int src_param_count = fn_type->data.fn.src_param_count;
3607 int actual_param_count = node->data.fn_call_expr.params.length;3603 int actual_param_count = node->data.fn_call_expr.params.length;
36083604
3609 if (struct_type) {3605 if (struct_type) {
3610 actual_param_count += 1;3606 actual_param_count += 1;
3611 }3607 }
36123608
3613 if (fn_proto->is_var_args) {3609 if (fn_type->data.fn.is_var_args) {
3614 if (actual_param_count < expected_param_count) {3610 if (actual_param_count < src_param_count) {
3615 add_node_error(g, node,3611 add_node_error(g, node,
3616 buf_sprintf("expected at least %d arguments, got %d",3612 buf_sprintf("expected at least %d arguments, got %d", src_param_count, actual_param_count));
3617 expected_param_count, actual_param_count));
3618 }3613 }
3619 } else if (expected_param_count != actual_param_count) {3614 } else if (src_param_count != actual_param_count) {
3620 add_node_error(g, node,3615 add_node_error(g, node,
3621 buf_sprintf("expected %d arguments, got %d",3616 buf_sprintf("expected %d arguments, got %d", src_param_count, actual_param_count));
3622 expected_param_count, actual_param_count));
3623 }3617 }
36243618
3625 // analyze each parameter. in the case of a method, we already analyzed the3619 // analyze each parameter. in the case of a method, we already analyzed the
...@@ -3629,19 +3623,13 @@ static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import,...@@ -3629,19 +3623,13 @@ static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import,
3629 // determine the expected type for each parameter3623 // determine the expected type for each parameter
3630 TypeTableEntry *expected_param_type = nullptr;3624 TypeTableEntry *expected_param_type = nullptr;
3631 int fn_proto_i = i + (struct_type ? 1 : 0);3625 int fn_proto_i = i + (struct_type ? 1 : 0);
3632 if (fn_proto_i < fn_proto->params.length) {3626 if (fn_proto_i < src_param_count) {
3633 AstNode *param_decl_node = fn_proto->params.at(fn_proto_i);3627 expected_param_type = fn_type->data.fn.param_types[fn_proto_i];
3634 assert(param_decl_node->type == NodeTypeParamDecl);
3635 AstNode *param_type_node = param_decl_node->data.param_decl.type;
3636 TypeTableEntry *param_type_entry = get_resolved_expr(param_type_node)->type_entry;
3637 if (param_type_entry) {
3638 expected_param_type = unwrapped_node_type(param_type_node);
3639 }
3640 }3628 }
3641 analyze_expression(g, import, context, expected_param_type, child);3629 analyze_expression(g, import, context, expected_param_type, child);
3642 }3630 }
36433631
3644 TypeTableEntry *return_type = unwrapped_node_type(fn_proto->return_type);3632 TypeTableEntry *return_type = fn_type->data.fn.src_return_type;
36453633
3646 if (return_type->id == TypeTableEntryIdInvalid) {3634 if (return_type->id == TypeTableEntryIdInvalid) {
3647 return return_type;3635 return return_type;
...@@ -3654,6 +3642,17 @@ static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import,...@@ -3654,6 +3642,17 @@ static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import,
3654 return return_type;3642 return return_type;
3655}3643}
36563644
3645static TypeTableEntry *analyze_fn_call_raw(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3646 TypeTableEntry *expected_type, AstNode *node, FnTableEntry *fn_table_entry, TypeTableEntry *struct_type)
3647{
3648 assert(node->type == NodeTypeFnCallExpr);
3649
3650 node->data.fn_call_expr.fn_entry = fn_table_entry;
3651
3652 return analyze_fn_call_ptr(g, import, context, expected_type, node, fn_table_entry->type_entry, struct_type);
3653
3654}
3655
3657static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,3656static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3658 TypeTableEntry *expected_type, AstNode *node)3657 TypeTableEntry *expected_type, AstNode *node)
3659{3658{
...@@ -3761,7 +3760,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import...@@ -3761,7 +3760,7 @@ static TypeTableEntry *analyze_fn_call_expr(CodeGen *g, ImportTableEntry *import
37613760
3762 // function pointer3761 // function pointer
3763 if (invoke_type_entry->id == TypeTableEntryIdFn) {3762 if (invoke_type_entry->id == TypeTableEntryIdFn) {
3764 return invoke_type_entry->data.fn.src_return_type;3763 return analyze_fn_call_ptr(g, import, context, expected_type, node, invoke_type_entry, nullptr);
3765 } else {3764 } else {
3766 add_node_error(g, fn_ref_expr,3765 add_node_error(g, fn_ref_expr,
3767 buf_sprintf("type '%s' not a function", buf_ptr(&invoke_type_entry->name)));3766 buf_sprintf("type '%s' not a function", buf_ptr(&invoke_type_entry->name)));
test/run_tests.cpp+23
...@@ -1823,6 +1823,29 @@ const x : u8 = 300;...@@ -1823,6 +1823,29 @@ const x : u8 = 300;
1823const x = 2 == 2.0;1823const x = 2 == 2.0;
1824 )SOURCE", 1, ".tmp_source.zig:2:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");1824 )SOURCE", 1, ".tmp_source.zig:2:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
18251825
1826 add_compile_fail_case("missing function call param", R"SOURCE(
1827struct Foo {
1828 a: i32,
1829 b: i32,
1830
1831 fn member_a(foo: Foo) -> i32 {
1832 return foo.a;
1833 }
1834 fn member_b(foo: Foo) -> i32 {
1835 return foo.b;
1836 }
1837}
1838
1839const member_fn_type = @typeof(Foo.member_a);
1840const members = []member_fn_type {
1841 Foo.member_a,
1842 Foo.member_b,
1843};
1844
1845fn f(foo: Foo, index: i32) {
1846 const result = members[index]();
1847}
1848 )SOURCE", 1, ".tmp_source.zig:21:34: error: expected 1 arguments, got 0");
1826}1849}
18271850
1828//////////////////////////////////////////////////////////////////////////////1851//////////////////////////////////////////////////////////////////////////////