| ... | ... | @@ -19706,18 +19706,26 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 19706 | 19706 | return ira->codegen->invalid_inst_gen; |
| 19707 | 19707 | } |
| 19708 | 19708 | |
| 19709 | bool extern_fn_in_typeof = false; |
| 19710 | |
| 19709 | 19711 | if (modifier == CallModifierCompileTime) { |
| 19710 | 19712 | // No special handling is needed for compile time evaluation of generic functions. |
| 19711 | 19713 | if (!fn_entry || fn_entry->body_node == nullptr) { |
| 19712 | | ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); |
| 19713 | | return ira->codegen->invalid_inst_gen; |
| 19714 | // We keep evaluating extern functions in TypeOfs |
| 19715 | if (get_scope_typeof(source_instr->scope) != nullptr && fn_entry) { |
| 19716 | extern_fn_in_typeof = true; |
| 19717 | } else { |
| 19718 | ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); |
| 19719 | return ira->codegen->invalid_inst_gen; |
| 19720 | } |
| 19714 | 19721 | } |
| 19715 | 19722 | |
| 19716 | 19723 | if (!ir_emit_backward_branch(ira, source_instr)) |
| 19717 | 19724 | return ira->codegen->invalid_inst_gen; |
| 19718 | 19725 | |
| 19719 | 19726 | // Fork a scope of the function with known values for the parameters. |
| 19720 | | Scope *exec_scope = &fn_entry->fndef_scope->base; |
| 19727 | // If we are evaluating an extern function in a TypeOf, we use the TypeOf's scope instead. |
| 19728 | Scope *exec_scope = extern_fn_in_typeof ? source_instr->scope : &fn_entry->fndef_scope->base; |
| 19721 | 19729 | |
| 19722 | 19730 | size_t next_proto_i = 0; |
| 19723 | 19731 | if (first_arg_ptr) { |
| ... | ... | @@ -19766,7 +19774,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 19766 | 19774 | return_type = specified_return_type; |
| 19767 | 19775 | } |
| 19768 | 19776 | |
| 19769 | | bool cacheable = fn_eval_cacheable(exec_scope, return_type); |
| 19777 | bool cacheable = !extern_fn_in_typeof && fn_eval_cacheable(exec_scope, return_type); |
| 19770 | 19778 | ZigValue *result = nullptr; |
| 19771 | 19779 | if (cacheable) { |
| 19772 | 19780 | auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); |
| ... | ... | @@ -19779,12 +19787,16 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 19779 | 19787 | AstNode *body_node = fn_entry->body_node; |
| 19780 | 19788 | ZigValue *result_ptr; |
| 19781 | 19789 | create_result_ptr(ira->codegen, return_type, &result, &result_ptr); |
| 19782 | | if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, |
| 19783 | | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, |
| 19784 | | fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, |
| 19785 | | UndefOk))) |
| 19786 | | { |
| 19787 | | return ira->codegen->invalid_inst_gen; |
| 19790 | |
| 19791 | // If we are evaluating an extern function in a TypeOf, create a value and keep it undefined. |
| 19792 | if (!extern_fn_in_typeof) { |
| 19793 | if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, |
| 19794 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, |
| 19795 | fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, |
| 19796 | UndefOk))) |
| 19797 | { |
| 19798 | return ira->codegen->invalid_inst_gen; |
| 19799 | } |
| 19788 | 19800 | } |
| 19789 | 19801 | |
| 19790 | 19802 | if (inferred_err_set_type != nullptr) { |