aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-01-13 11:48:54 -0500
committerGitHub <noreply@github.com>2020-01-13 11:48:54 -0500
commit4d4852ad31aa373d85cc43eb8631474323300b57 (patch)
treeec6878a86de3297c3e85c9b52adc9cc54c56de69 /src/ir.cpp
parentd08009556eea9cb6d5dea273340081e599d7741b (diff)
parent54b11f66a960ba8f91697ede36b31934f05acfee (diff)
downloadzig-4d4852ad31aa373d85cc43eb8631474323300b57.tar.gz
zig-4d4852ad31aa373d85cc43eb8631474323300b57.zip
Merge pull request #4162 from LemonBoy/fix-4020
Fix @call being too eager to resolve the fn argument
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp52
1 files changed, 35 insertions, 17 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 340b27119a..a5561e9bfd 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -18687,18 +18687,6 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc
IrInstruction *fn_ref = pass1_fn_ref->child;
if (type_is_invalid(fn_ref->value->type))
return ira->codegen->invalid_instruction;
- IrInstruction *first_arg_ptr = nullptr;
- ZigFn *fn = nullptr;
- if (fn_ref->value->type->id == ZigTypeIdBoundFn) {
- assert(fn_ref->value->special == ConstValSpecialStatic);
- fn = fn_ref->value->data.x_bound_fn.fn;
- first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg;
- if (type_is_invalid(first_arg_ptr->value->type))
- return ira->codegen->invalid_instruction;
- } else {
- fn = ir_resolve_fn(ira, fn_ref);
- }
- ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type;
TypeStructField *modifier_field = find_struct_type_field(options->value->type, buf_create_from_str("modifier"));
ir_assert(modifier_field != nullptr, source_instr);
@@ -18733,22 +18721,52 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc
}
}
+ IrInstruction *first_arg_ptr = nullptr;
+ ZigFn *fn = nullptr;
+ if (instr_is_comptime(fn_ref)) {
+ if (fn_ref->value->type->id == ZigTypeIdBoundFn) {
+ assert(fn_ref->value->special == ConstValSpecialStatic);
+ fn = fn_ref->value->data.x_bound_fn.fn;
+ first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg;
+ if (type_is_invalid(first_arg_ptr->value->type))
+ return ira->codegen->invalid_instruction;
+ } else {
+ fn = ir_resolve_fn(ira, fn_ref);
+ }
+ }
+
+ // Some modifiers require the callee to be comptime-known
+ switch (modifier) {
+ case CallModifierCompileTime:
+ case CallModifierAlwaysInline:
+ case CallModifierAsync:
+ if (fn == nullptr) {
+ ir_add_error(ira, modifier_inst,
+ buf_sprintf("the specified modifier requires a comptime-known function"));
+ return ira->codegen->invalid_instruction;
+ }
+ default:
+ break;
+ }
+
+ ZigType *fn_type = (fn != nullptr) ? fn->type_entry : fn_ref->value->type;
+
TypeStructField *stack_field = find_struct_type_field(options->value->type, buf_create_from_str("stack"));
ir_assert(stack_field != nullptr, source_instr);
IrInstruction *opt_stack = ir_analyze_struct_value_field_value(ira, source_instr, options, stack_field);
if (type_is_invalid(opt_stack->value->type))
return ira->codegen->invalid_instruction;
+
IrInstruction *stack_is_non_null_inst = ir_analyze_test_non_null(ira, source_instr, opt_stack);
bool stack_is_non_null;
if (!ir_resolve_bool(ira, stack_is_non_null_inst, &stack_is_non_null))
return ira->codegen->invalid_instruction;
- IrInstruction *stack;
+
+ IrInstruction *stack = nullptr;
if (stack_is_non_null) {
stack = ir_analyze_optional_value_payload_value(ira, source_instr, opt_stack, false);
- if (type_is_invalid(stack->value->type))
- return ira->codegen->invalid_instruction;
- } else {
- stack = nullptr;
+ if (type_is_invalid(stack->value->type))
+ return ira->codegen->invalid_instruction;
}
return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr,