| ... | @@ -15419,6 +15419,12 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns | ... | @@ -15419,6 +15419,12 @@ static IrInstGen *ir_get_deref(IrAnalyze *ira, IrInst* source_instruction, IrIns |
| 15419 | } | 15419 | } |
| 15420 | if (instr_is_comptime(ptr)) { | 15420 | if (instr_is_comptime(ptr)) { |
| 15421 | if (ptr->value->special == ConstValSpecialUndef) { | 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 | ir_add_error(ira, &ptr->base, buf_sprintf("attempt to dereference undefined value")); | 15428 | ir_add_error(ira, &ptr->base, buf_sprintf("attempt to dereference undefined value")); |
| 15423 | return ira->codegen->invalid_inst_gen; | 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,6 +19726,20 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 19720 | } | 19726 | } |
| 19721 | | 19727 | |
| 19722 | if (modifier == CallModifierCompileTime) { | 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 | // No special handling is needed for compile time evaluation of generic functions. | 19743 | // No special handling is needed for compile time evaluation of generic functions. |
| 19724 | if (!fn_entry || fn_entry->body_node == nullptr) { | 19744 | if (!fn_entry || fn_entry->body_node == nullptr) { |
| 19725 | ir_add_error(ira, &fn_ref->base, buf_sprintf("unable to evaluate constant expression")); | 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,6 +19812,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr, |
| 19792 | AstNode *body_node = fn_entry->body_node; | 19812 | AstNode *body_node = fn_entry->body_node; |
| 19793 | ZigValue *result_ptr; | 19813 | ZigValue *result_ptr; |
| 19794 | create_result_ptr(ira->codegen, return_type, &result, &result_ptr); | 19814 | create_result_ptr(ira->codegen, return_type, &result, &result_ptr); |
| | 19815 | |
| 19795 | if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, | 19816 | if ((err = ir_eval_const_value(ira->codegen, exec_scope, body_node, result_ptr, |
| 19796 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, | 19817 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, |
| 19797 | fn_entry, nullptr, source_instr->source_node, nullptr, ira->new_irb.exec, return_type_node, | 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,6 +21883,11 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name |
| 21862 | return ir_analyze_inferred_field_ptr(ira, field_name, source_instr, container_ptr, bare_type); | 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 | if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown))) | 21891 | if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown))) |
| 21866 | return ira->codegen->invalid_inst_gen; | 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,6 +21895,12 @@ static IrInstGen *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name |
| 21869 | if (bare_type->id == ZigTypeIdStruct) { | 21895 | if (bare_type->id == ZigTypeIdStruct) { |
| 21870 | TypeStructField *field = find_struct_type_field(bare_type, field_name); | 21896 | TypeStructField *field = find_struct_type_field(bare_type, field_name); |
| 21871 | if (field != nullptr) { | 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 | return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); | 21904 | return ir_analyze_struct_field_ptr(ira, source_instr, field, container_ptr, bare_type, initializing); |
| 21873 | } else { | 21905 | } else { |
| 21874 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, | 21906 | return ir_analyze_container_member_access_inner(ira, bare_type, field_name, |