| ... | ... | @@ -15419,6 +15419,12 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns |
| 15419 | 15419 | } |
| 15420 | 15420 | if (instr_is_comptime(ptr)) { |
| 15421 | 15421 | if (ptr->value->special == ConstValSpecialUndef) { |
| 15422 | // If we are in a TypeOf call, we return an undefined value instead of erroring |
| 15423 | // since we know the type. |
| 15424 | if (get_scope_typeof(source_instruction->scope)) { |
| 15425 | return ir_const_undef(ira, source_instruction, child_type); |
| 15426 | } |
| 15427 | |
| 15422 | 15428 | ir_add_error(ira, &ptr->base, buf_sprintf("attempt to dereference undefined value")); |
| 15423 | 15429 | return ira->codegen->invalid_inst_gen; |
| 15424 | 15430 | } |
| ... | ... | @@ -19720,6 +19726,20 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 19720 | 19726 | } |
| 19721 | 19727 | |
| 19722 | 19728 | if (modifier == CallModifierCompileTime) { |
| 19729 | // If we are evaluating an extern function in a TypeOf call, we can return an undefined value |
| 19730 | // of its return type. |
| 19731 | if (fn_entry != nullptr && get_scope_typeof(source_instr->scope) != nullptr && |
| 19732 | fn_proto_node->data.fn_proto.is_extern) { |
| 19733 | |
| 19734 | assert(fn_entry->body_node == nullptr); |
| 19735 | AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; |
| 19736 | ZigType *return_type = ir_analyze_type_expr(ira, source_instr->scope, return_type_node); |
| 19737 | if (type_is_invalid(return_type)) |
| 19738 | return ira->codegen->invalid_inst_gen; |
| 19739 | |
| 19740 | return ir_const_undef(ira, source_instr, return_type); |
| 19741 | } |
| 19742 | |
| 19723 | 19743 | // No special handling is needed for compile time evaluation of generic functions. |
| 19724 | 19744 | if (!fn_entry || fn_entry->body_node == nullptr) { |
| 19725 | 19745 | ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); |
| ... | ... | @@ -19792,6 +19812,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 19792 | 19812 | AstNode *body_node = fn_entry->body_node; |
| 19793 | 19813 | ZigValue *result_ptr; |
| 19794 | 19814 | create_result_ptr(ira->codegen, return_type, &result, &result_ptr); |
| 19815 | |
| 19795 | 19816 | if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, |
| 19796 | 19817 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, |
| 19797 | 19818 | fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, |
| ... | ... | @@ -21862,6 +21883,11 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name |
| 21862 | 21883 | return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type); |
| 21863 | 21884 | } |
| 21864 | 21885 | |
| 21886 | // Tracks wether we should return an undefined value of the correct type. |
| 21887 | // We do this if the container pointer is undefined and we are in a TypeOf call. |
| 21888 | bool return_undef = container_ptr->value->special == ConstValSpecialUndef && \ |
| 21889 | get_scope_typeof(source_instr->scope) != nullptr; |
| 21890 | |
| 21865 | 21891 | if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown))) |
| 21866 | 21892 | return ira->codegen->invalid_inst_gen; |
| 21867 | 21893 | |
| ... | ... | @@ -21869,6 +21895,12 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name |
| 21869 | 21895 | if (bare_type->id == ZigTypeIdStruct) { |
| 21870 | 21896 | TypeStructField *field = find_struct_type_field(bare_type, field_name); |
| 21871 | 21897 | if (field != nullptr) { |
| 21898 | if (return_undef) { |
| 21899 | ZigType *field_ptr_type = get_pointer_to_type(ira->codegen, resolve_struct_field_type(ira->codegen, field), |
| 21900 | container_ptr->value->type->data.pointer.is_const); |
| 21901 | return ir_const_undef(ira, source_instr, field_ptr_type); |
| 21902 | } |
| 21903 | |
| 21872 | 21904 | return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); |
| 21873 | 21905 | } else { |
| 21874 | 21906 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |