| ... | ... | @@ -1250,7 +1250,7 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t |
| 1250 | 1250 | if (!fn_table_entry->is_extern) { |
| 1251 | 1251 | LLVMAddFunctionAttr(fn_table_entry->fn_value, LLVMNoUnwindAttribute); |
| 1252 | 1252 | } |
| 1253 | | if (!g->is_release_build && !fn_proto->is_inline) { |
| 1253 | if (!g->is_release_build && fn_table_entry->fn_inline != FnInlineAlways) { |
| 1254 | 1254 | ZigLLVMAddFunctionAttr(fn_table_entry->fn_value, "no-frame-pointer-elim", "true"); |
| 1255 | 1255 | ZigLLVMAddFunctionAttr(fn_table_entry->fn_value, "no-frame-pointer-elim-non-leaf", nullptr); |
| 1256 | 1256 | } |
| ... | ... | @@ -5453,19 +5453,20 @@ static TypeTableEntry *analyze_fn_call_ptr(CodeGen *g, ImportTableEntry *import, |
| 5453 | 5453 | int src_param_count = fn_type->data.fn.fn_type_id.param_count + |
| 5454 | 5454 | (generic_proto_node ? generic_proto_node->data.fn_proto.inline_arg_count : 0); |
| 5455 | 5455 | int call_param_count = node->data.fn_call_expr.params.length; |
| 5456 | int expect_arg_count = src_param_count - struct_node_1_or_0; |
| 5456 | 5457 | |
| 5457 | 5458 | bool ok_invocation = true; |
| 5458 | 5459 | |
| 5459 | 5460 | if (fn_type->data.fn.fn_type_id.is_var_args) { |
| 5460 | | if (call_param_count < src_param_count - struct_node_1_or_0) { |
| 5461 | if (call_param_count < expect_arg_count) { |
| 5461 | 5462 | ok_invocation = false; |
| 5462 | 5463 | add_node_error(g, node, |
| 5463 | 5464 | buf_sprintf("expected at least %d arguments, got %d", src_param_count, call_param_count)); |
| 5464 | 5465 | } |
| 5465 | | } else if (src_param_count - struct_node_1_or_0 != call_param_count) { |
| 5466 | } else if (expect_arg_count != call_param_count) { |
| 5466 | 5467 | ok_invocation = false; |
| 5467 | 5468 | add_node_error(g, node, |
| 5468 | | buf_sprintf("expected %d arguments, got %d", src_param_count, call_param_count)); |
| 5469 | buf_sprintf("expected %d arguments, got %d", expect_arg_count, call_param_count)); |
| 5469 | 5470 | } |
| 5470 | 5471 | |
| 5471 | 5472 | bool all_args_const_expr = true; |
| ... | ... | @@ -5567,7 +5568,7 @@ static TypeTableEntry *analyze_fn_call_with_inline_args(CodeGen *g, ImportTableE |
| 5567 | 5568 | |
| 5568 | 5569 | if (src_param_count != call_param_count + struct_node_1_or_0) { |
| 5569 | 5570 | add_node_error(g, call_node, |
| 5570 | | buf_sprintf("expected %d arguments, got %d", src_param_count, call_param_count)); |
| 5571 | buf_sprintf("expected %d arguments, got %d", src_param_count - struct_node_1_or_0, call_param_count)); |
| 5571 | 5572 | return g->builtin_types.entry_invalid; |
| 5572 | 5573 | } |
| 5573 | 5574 | |
| ... | ... | @@ -6821,13 +6822,18 @@ static void count_inline_and_var_args(AstNode *proto_node) { |
| 6821 | 6822 | *inline_arg_count = 0; |
| 6822 | 6823 | *inline_or_var_type_arg_count = 0; |
| 6823 | 6824 | |
| 6825 | // TODO run these nodes through the type analysis system rather than looking for |
| 6826 | // specialized ast nodes. this would get fooled by `{var}` instead of `var` which |
| 6827 | // is supposed to be equivalent |
| 6824 | 6828 | for (int i = 0; i < proto_node->data.fn_proto.params.length; i += 1) { |
| 6825 | 6829 | AstNode *param_node = proto_node->data.fn_proto.params.at(i); |
| 6826 | 6830 | assert(param_node->type == NodeTypeParamDecl); |
| 6827 | | bool is_inline = param_node->data.param_decl.is_inline; |
| 6828 | | *inline_arg_count += is_inline ? 1 : 0; |
| 6829 | | *inline_or_var_type_arg_count += (is_inline || |
| 6830 | | param_node->data.param_decl.type->type == NodeTypeVarLiteral) ? 1 : 0; |
| 6831 | if (param_node->data.param_decl.is_inline) { |
| 6832 | *inline_arg_count += 1; |
| 6833 | *inline_or_var_type_arg_count += 1; |
| 6834 | } else if (param_node->data.param_decl.type->type == NodeTypeVarLiteral) { |
| 6835 | *inline_or_var_type_arg_count += 1; |
| 6836 | } |
| 6831 | 6837 | } |
| 6832 | 6838 | } |
| 6833 | 6839 | |