| ... | ... | @@ -155,6 +155,7 @@ struct ConstCastBadAllowsZero { |
| 155 | 155 | enum UndefAllowed { |
| 156 | 156 | UndefOk, |
| 157 | 157 | UndefBad, |
| 158 | LazyOk, |
| 158 | 159 | }; |
| 159 | 160 | |
| 160 | 161 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| ... | ... | @@ -403,7 +404,7 @@ static void ir_ref_var(ZigVar *var) { |
| 403 | 404 | ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) { |
| 404 | 405 | ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type, |
| 405 | 406 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr, |
| 406 | | node, nullptr, ira->new_irb.exec, nullptr); |
| 407 | node, nullptr, ira->new_irb.exec, nullptr, false); |
| 407 | 408 | |
| 408 | 409 | if (type_is_invalid(result->type)) |
| 409 | 410 | return ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -10710,32 +10711,57 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio |
| 10710 | 10711 | return const_instr; |
| 10711 | 10712 | } |
| 10712 | 10713 | |
| 10714 | static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 10715 | ConstExprValue *val, UndefAllowed undef_allowed) |
| 10716 | { |
| 10717 | Error err; |
| 10718 | for (;;) { |
| 10719 | switch (val->special) { |
| 10720 | case ConstValSpecialStatic: |
| 10721 | return ErrorNone; |
| 10722 | case ConstValSpecialRuntime: |
| 10723 | if (!type_has_bits(val->type)) |
| 10724 | return ErrorNone; |
| 10725 | |
| 10726 | exec_add_error_node(codegen, exec, source_node, |
| 10727 | buf_sprintf("unable to evaluate constant expression")); |
| 10728 | return ErrorSemanticAnalyzeFail; |
| 10729 | case ConstValSpecialUndef: |
| 10730 | if (undef_allowed == UndefOk) |
| 10731 | return ErrorNone; |
| 10732 | |
| 10733 | exec_add_error_node(codegen, exec, source_node, |
| 10734 | buf_sprintf("use of undefined value here causes undefined behavior")); |
| 10735 | return ErrorSemanticAnalyzeFail; |
| 10736 | case ConstValSpecialLazy: |
| 10737 | if (undef_allowed == LazyOk) |
| 10738 | return ErrorNone; |
| 10739 | |
| 10740 | if ((err = ir_resolve_lazy(codegen, source_node, val))) |
| 10741 | return err; |
| 10742 | |
| 10743 | continue; |
| 10744 | } |
| 10745 | } |
| 10746 | } |
| 10747 | |
| 10713 | 10748 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { |
| 10714 | | switch (value->value.special) { |
| 10715 | | case ConstValSpecialStatic: |
| 10716 | | return &value->value; |
| 10717 | | case ConstValSpecialRuntime: |
| 10718 | | if (!type_has_bits(value->value.type)) { |
| 10719 | | return &value->value; |
| 10720 | | } |
| 10721 | | ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); |
| 10722 | | return nullptr; |
| 10723 | | case ConstValSpecialUndef: |
| 10724 | | if (undef_allowed == UndefOk) { |
| 10725 | | return &value->value; |
| 10726 | | } else { |
| 10727 | | ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior")); |
| 10728 | | return nullptr; |
| 10729 | | } |
| 10749 | Error err; |
| 10750 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->source_node, |
| 10751 | &value->value, undef_allowed))) |
| 10752 | { |
| 10753 | return nullptr; |
| 10730 | 10754 | } |
| 10731 | | zig_unreachable(); |
| 10755 | return &value->value; |
| 10732 | 10756 | } |
| 10733 | 10757 | |
| 10734 | 10758 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 10735 | 10759 | ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota, |
| 10736 | 10760 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, |
| 10737 | | IrExecutable *parent_exec, AstNode *expected_type_source_node) |
| 10761 | IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy) |
| 10738 | 10762 | { |
| 10763 | Error err; |
| 10764 | |
| 10739 | 10765 | if (expected_type != nullptr && type_is_invalid(expected_type)) |
| 10740 | 10766 | return &codegen->invalid_instruction->value; |
| 10741 | 10767 | |
| ... | ... | @@ -10784,7 +10810,14 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 10784 | 10810 | fprintf(stderr, "}\n"); |
| 10785 | 10811 | } |
| 10786 | 10812 | |
| 10787 | | return ir_exec_const_result(codegen, analyzed_executable); |
| 10813 | ConstExprValue *result = ir_exec_const_result(codegen, analyzed_executable); |
| 10814 | |
| 10815 | if (!allow_lazy) { |
| 10816 | if ((err = ir_resolve_lazy(codegen, node, result))) |
| 10817 | return &codegen->invalid_instruction->value; |
| 10818 | } |
| 10819 | |
| 10820 | return result; |
| 10788 | 10821 | } |
| 10789 | 10822 | |
| 10790 | 10823 | static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_value) { |
| ... | ... | @@ -10805,6 +10838,17 @@ static ErrorTableEntry *ir_resolve_error(IrAnalyze *ira, IrInstruction *err_valu |
| 10805 | 10838 | return const_val->data.x_err_set; |
| 10806 | 10839 | } |
| 10807 | 10840 | |
| 10841 | static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 10842 | ConstExprValue *val) |
| 10843 | { |
| 10844 | Error err; |
| 10845 | if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) |
| 10846 | return codegen->builtin_types.entry_invalid; |
| 10847 | |
| 10848 | assert(val->data.x_type != nullptr); |
| 10849 | return val->data.x_type; |
| 10850 | } |
| 10851 | |
| 10808 | 10852 | static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| 10809 | 10853 | if (type_is_invalid(type_value->value.type)) |
| 10810 | 10854 | return ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -10815,12 +10859,7 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| 10815 | 10859 | return ira->codegen->builtin_types.entry_invalid; |
| 10816 | 10860 | } |
| 10817 | 10861 | |
| 10818 | | ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); |
| 10819 | | if (!const_val) |
| 10820 | | return ira->codegen->builtin_types.entry_invalid; |
| 10821 | | |
| 10822 | | assert(const_val->data.x_type != nullptr); |
| 10823 | | return const_val->data.x_type; |
| 10862 | return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, &type_value->value); |
| 10824 | 10863 | } |
| 10825 | 10864 | |
| 10826 | 10865 | static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) { |
| ... | ... | @@ -12500,26 +12539,22 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 12500 | 12539 | return ir_build_load_ptr_gen(ira, source_instruction, ptr, child_type, result_loc_inst); |
| 12501 | 12540 | } |
| 12502 | 12541 | |
| 12503 | | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { |
| 12504 | | if (type_is_invalid(value->value.type)) |
| 12505 | | return false; |
| 12506 | | |
| 12507 | | IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); |
| 12508 | | if (type_is_invalid(casted_value->value.type)) |
| 12509 | | return false; |
| 12510 | | |
| 12511 | | ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); |
| 12512 | | if (!const_val) |
| 12542 | static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 12543 | ConstExprValue *const_val, uint32_t *out) |
| 12544 | { |
| 12545 | Error err; |
| 12546 | if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) |
| 12513 | 12547 | return false; |
| 12514 | 12548 | |
| 12515 | 12549 | uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); |
| 12516 | 12550 | if (align_bytes == 0) { |
| 12517 | | ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); |
| 12551 | exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); |
| 12518 | 12552 | return false; |
| 12519 | 12553 | } |
| 12520 | 12554 | |
| 12521 | 12555 | if (!is_power_of_2(align_bytes)) { |
| 12522 | | ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); |
| 12556 | exec_add_error_node(codegen, exec, source_node, |
| 12557 | buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); |
| 12523 | 12558 | return false; |
| 12524 | 12559 | } |
| 12525 | 12560 | |
| ... | ... | @@ -12527,6 +12562,18 @@ static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out |
| 12527 | 12562 | return true; |
| 12528 | 12563 | } |
| 12529 | 12564 | |
| 12565 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { |
| 12566 | if (type_is_invalid(value->value.type)) |
| 12567 | return false; |
| 12568 | |
| 12569 | IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); |
| 12570 | if (type_is_invalid(casted_value->value.type)) |
| 12571 | return false; |
| 12572 | |
| 12573 | return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->source_node, |
| 12574 | &casted_value->value, out); |
| 12575 | } |
| 12576 | |
| 12530 | 12577 | static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { |
| 12531 | 12578 | if (type_is_invalid(value->value.type)) |
| 12532 | 12579 | return false; |
| ... | ... | @@ -14151,7 +14198,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14151 | 14198 | } |
| 14152 | 14199 | } |
| 14153 | 14200 | |
| 14154 | | switch (type_requires_comptime(ira->codegen, result_type)) { |
| 14201 | switch (type_requires_comptime(ira->codegen, result_type, nullptr)) { |
| 14155 | 14202 | case ReqCompTimeInvalid: |
| 14156 | 14203 | result_type = ira->codegen->builtin_types.entry_invalid; |
| 14157 | 14204 | break; |
| ... | ... | @@ -15113,7 +15160,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 15113 | 15160 | } |
| 15114 | 15161 | |
| 15115 | 15162 | if (!comptime_arg) { |
| 15116 | | switch (type_requires_comptime(ira->codegen, casted_arg->value.type)) { |
| 15163 | switch (type_requires_comptime(ira->codegen, casted_arg->value.type, nullptr)) { |
| 15117 | 15164 | case ReqCompTimeYes: |
| 15118 | 15165 | ir_add_error(ira, casted_arg, |
| 15119 | 15166 | buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value.type->name))); |
| ... | ... | @@ -15192,6 +15239,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 15192 | 15239 | case ConstValSpecialRuntime: |
| 15193 | 15240 | goto no_mem_slot; |
| 15194 | 15241 | case ConstValSpecialStatic: // fallthrough |
| 15242 | case ConstValSpecialLazy: // fallthrough |
| 15195 | 15243 | case ConstValSpecialUndef: { |
| 15196 | 15244 | ConstPtrMut ptr_mut; |
| 15197 | 15245 | if (comptime_var_mem) { |
| ... | ... | @@ -15313,7 +15361,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 15313 | 15361 | } |
| 15314 | 15362 | } |
| 15315 | 15363 | |
| 15316 | | switch (type_requires_comptime(ira->codegen, child_type)) { |
| 15364 | switch (type_requires_comptime(ira->codegen, child_type, nullptr)) { |
| 15317 | 15365 | case ReqCompTimeInvalid: |
| 15318 | 15366 | return ira->codegen->invalid_instruction; |
| 15319 | 15367 | case ReqCompTimeYes: |
| ... | ... | @@ -15483,7 +15531,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15483 | 15531 | AstNode *body_node = fn_entry->body_node; |
| 15484 | 15532 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 15485 | 15533 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, |
| 15486 | | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node); |
| 15534 | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, false); |
| 15487 | 15535 | |
| 15488 | 15536 | if (inferred_err_set_type != nullptr) { |
| 15489 | 15537 | inferred_err_set_type->data.error_set.infer_fn = nullptr; |
| ... | ... | @@ -15680,7 +15728,8 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15680 | 15728 | ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, |
| 15681 | 15729 | fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), |
| 15682 | 15730 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, |
| 15683 | | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); |
| 15731 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, |
| 15732 | nullptr, false); |
| 15684 | 15733 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 15685 | 15734 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 15686 | 15735 | copy_const_val(&const_instruction->base.value, align_result, true); |
| ... | ... | @@ -15705,7 +15754,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c |
| 15705 | 15754 | inst_fn_type_id.return_type = specified_return_type; |
| 15706 | 15755 | } |
| 15707 | 15756 | |
| 15708 | | switch (type_requires_comptime(ira->codegen, specified_return_type)) { |
| 15757 | switch (type_requires_comptime(ira->codegen, specified_return_type, nullptr)) { |
| 15709 | 15758 | case ReqCompTimeYes: |
| 15710 | 15759 | // Throw out our work and call the function as if it were comptime. |
| 15711 | 15760 | return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, |
| ... | ... | @@ -16512,7 +16561,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16512 | 16561 | break; |
| 16513 | 16562 | } |
| 16514 | 16563 | |
| 16515 | | switch (type_requires_comptime(ira->codegen, resolved_type)) { |
| 16564 | switch (type_requires_comptime(ira->codegen, resolved_type, nullptr)) { |
| 16516 | 16565 | case ReqCompTimeInvalid: |
| 16517 | 16566 | return ira->codegen->invalid_instruction; |
| 16518 | 16567 | case ReqCompTimeYes: |
| ... | ... | @@ -16960,7 +17009,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 16960 | 17009 | } |
| 16961 | 17010 | } else { |
| 16962 | 17011 | // runtime known element index |
| 16963 | | switch (type_requires_comptime(ira->codegen, return_type)) { |
| 17012 | switch (type_requires_comptime(ira->codegen, return_type, nullptr)) { |
| 16964 | 17013 | case ReqCompTimeYes: |
| 16965 | 17014 | ir_add_error(ira, elem_index, |
| 16966 | 17015 | buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", |
| ... | ... | @@ -17839,22 +17888,29 @@ static IrInstruction *ir_analyze_instruction_any_frame_type(IrAnalyze *ira, |
| 17839 | 17888 | static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 17840 | 17889 | IrInstructionSliceType *slice_type_instruction) |
| 17841 | 17890 | { |
| 17842 | | Error err; |
| 17843 | | uint32_t align_bytes = 0; |
| 17891 | IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type); |
| 17892 | result->value.special = ConstValSpecialLazy; |
| 17893 | |
| 17894 | LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1); |
| 17895 | result->value.data.x_lazy = &lazy_slice_type->base; |
| 17896 | lazy_slice_type->base.id = LazyValueIdSliceType; |
| 17897 | lazy_slice_type->base.exec = ira->new_irb.exec; |
| 17898 | |
| 17844 | 17899 | if (slice_type_instruction->align_value != nullptr) { |
| 17845 | | if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes)) |
| 17900 | lazy_slice_type->align_val = ir_resolve_const(ira, slice_type_instruction->align_value->child, LazyOk); |
| 17901 | if (lazy_slice_type->align_val == nullptr) |
| 17846 | 17902 | return ira->codegen->invalid_instruction; |
| 17847 | 17903 | } |
| 17848 | 17904 | |
| 17849 | | ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); |
| 17850 | | if (type_is_invalid(child_type)) |
| 17905 | lazy_slice_type->elem_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); |
| 17906 | if (type_is_invalid(lazy_slice_type->elem_type)) |
| 17851 | 17907 | return ira->codegen->invalid_instruction; |
| 17852 | 17908 | |
| 17853 | | bool is_const = slice_type_instruction->is_const; |
| 17854 | | bool is_volatile = slice_type_instruction->is_volatile; |
| 17855 | | bool is_allow_zero = slice_type_instruction->is_allow_zero; |
| 17909 | lazy_slice_type->is_const = slice_type_instruction->is_const; |
| 17910 | lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; |
| 17911 | lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; |
| 17856 | 17912 | |
| 17857 | | switch (child_type->id) { |
| 17913 | switch (lazy_slice_type->elem_type->id) { |
| 17858 | 17914 | case ZigTypeIdInvalid: // handled above |
| 17859 | 17915 | zig_unreachable(); |
| 17860 | 17916 | case ZigTypeIdUnreachable: |
| ... | ... | @@ -17863,7 +17919,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 17863 | 17919 | case ZigTypeIdArgTuple: |
| 17864 | 17920 | case ZigTypeIdOpaque: |
| 17865 | 17921 | ir_add_error_node(ira, slice_type_instruction->base.source_node, |
| 17866 | | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); |
| 17922 | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&lazy_slice_type->elem_type->name))); |
| 17867 | 17923 | return ira->codegen->invalid_instruction; |
| 17868 | 17924 | case ZigTypeIdMetaType: |
| 17869 | 17925 | case ZigTypeIdVoid: |
| ... | ... | @@ -17886,18 +17942,9 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 17886 | 17942 | case ZigTypeIdVector: |
| 17887 | 17943 | case ZigTypeIdFnFrame: |
| 17888 | 17944 | case ZigTypeIdAnyFrame: |
| 17889 | | { |
| 17890 | | ResolveStatus needed_status = (align_bytes == 0) ? |
| 17891 | | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; |
| 17892 | | if ((err = type_resolve(ira->codegen, child_type, needed_status))) |
| 17893 | | return ira->codegen->invalid_instruction; |
| 17894 | | ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 17895 | | is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0, is_allow_zero); |
| 17896 | | ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); |
| 17897 | | return ir_const_type(ira, &slice_type_instruction->base, result_type); |
| 17898 | | } |
| 17945 | break; |
| 17899 | 17946 | } |
| 17900 | | zig_unreachable(); |
| 17947 | return result; |
| 17901 | 17948 | } |
| 17902 | 17949 | |
| 17903 | 17950 | static IrInstruction *ir_analyze_instruction_global_asm(IrAnalyze *ira, IrInstructionGlobalAsm *instruction) { |
| ... | ... | @@ -18947,7 +18994,7 @@ static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *sourc |
| 18947 | 18994 | } |
| 18948 | 18995 | |
| 18949 | 18996 | bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope) |
| 18950 | | || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; |
| 18997 | || type_requires_comptime(ira->codegen, union_type, nullptr) == ReqCompTimeYes; |
| 18951 | 18998 | |
| 18952 | 18999 | IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); |
| 18953 | 19000 | if (is_comptime && !instr_is_comptime(result)) { |
| ... | ... | @@ -18995,7 +19042,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 18995 | 19042 | ZigList<IrInstruction *> const_ptrs = {}; |
| 18996 | 19043 | |
| 18997 | 19044 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) |
| 18998 | | || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; |
| 19045 | || type_requires_comptime(ira->codegen, container_type, nullptr) == ReqCompTimeYes; |
| 18999 | 19046 | |
| 19000 | 19047 | |
| 19001 | 19048 | // Here we iterate over the fields that have been initialized, and emit |
| ... | ... | @@ -19173,7 +19220,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 19173 | 19220 | } |
| 19174 | 19221 | |
| 19175 | 19222 | bool is_comptime; |
| 19176 | | switch (type_requires_comptime(ira->codegen, container_type)) { |
| 19223 | switch (type_requires_comptime(ira->codegen, container_type, nullptr)) { |
| 19177 | 19224 | case ReqCompTimeInvalid: |
| 19178 | 19225 | return ira->codegen->invalid_instruction; |
| 19179 | 19226 | case ReqCompTimeNo: |
| ... | ... | @@ -20575,7 +20622,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 20575 | 20622 | ZigType *void_type = ira->codegen->builtin_types.entry_void; |
| 20576 | 20623 | ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, |
| 20577 | 20624 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, |
| 20578 | | &cimport_scope->buf, block_node, nullptr, nullptr, nullptr); |
| 20625 | &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, false); |
| 20579 | 20626 | if (type_is_invalid(cimport_result->type)) |
| 20580 | 20627 | return ira->codegen->invalid_instruction; |
| 20581 | 20628 | |
| ... | ... | @@ -22243,15 +22290,11 @@ static IrInstruction *ir_analyze_instruction_frame_size(IrAnalyze *ira, IrInstru |
| 22243 | 22290 | } |
| 22244 | 22291 | |
| 22245 | 22292 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { |
| 22246 | | Error err; |
| 22247 | 22293 | IrInstruction *type_value = instruction->type_value->child; |
| 22248 | 22294 | if (type_is_invalid(type_value->value.type)) |
| 22249 | 22295 | return ira->codegen->invalid_instruction; |
| 22250 | 22296 | ZigType *type_entry = ir_resolve_type(ira, type_value); |
| 22251 | 22297 | |
| 22252 | | if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown))) |
| 22253 | | return ira->codegen->invalid_instruction; |
| 22254 | | |
| 22255 | 22298 | switch (type_entry->id) { |
| 22256 | 22299 | case ZigTypeIdInvalid: |
| 22257 | 22300 | zig_unreachable(); |
| ... | ... | @@ -22284,12 +22327,27 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct |
| 22284 | 22327 | case ZigTypeIdVector: |
| 22285 | 22328 | case ZigTypeIdFnFrame: |
| 22286 | 22329 | case ZigTypeIdAnyFrame: |
| 22287 | | { |
| 22288 | | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); |
| 22289 | | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); |
| 22290 | | } |
| 22330 | break; |
| 22291 | 22331 | } |
| 22292 | | zig_unreachable(); |
| 22332 | |
| 22333 | if (type_is_resolved(type_entry, ResolveStatusAlignmentKnown)) { |
| 22334 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); |
| 22335 | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); |
| 22336 | } |
| 22337 | |
| 22338 | // Here we create a lazy value in order to avoid resolving the alignment of the type |
| 22339 | // immediately. This avoids false positive dependency loops such as: |
| 22340 | // const Node = struct { |
| 22341 | // field: []align(@alignOf(Node)) Node, |
| 22342 | // }; |
| 22343 | LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); |
| 22344 | lazy_align_of->base.id = LazyValueIdAlignOf; |
| 22345 | lazy_align_of->base.exec = ira->new_irb.exec; |
| 22346 | lazy_align_of->target_type = type_entry; |
| 22347 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); |
| 22348 | result->value.special = ConstValSpecialLazy; |
| 22349 | result->value.data.x_lazy = &lazy_align_of->base; |
| 22350 | return result; |
| 22293 | 22351 | } |
| 22294 | 22352 | |
| 22295 | 22353 | static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { |
| ... | ... | @@ -22783,7 +22841,7 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 22783 | 22841 | if (type_is_invalid(param_type_value->value.type)) |
| 22784 | 22842 | return ira->codegen->invalid_instruction; |
| 22785 | 22843 | ZigType *param_type = ir_resolve_type(ira, param_type_value); |
| 22786 | | switch (type_requires_comptime(ira->codegen, param_type)) { |
| 22844 | switch (type_requires_comptime(ira->codegen, param_type, nullptr)) { |
| 22787 | 22845 | case ReqCompTimeYes: |
| 22788 | 22846 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { |
| 22789 | 22847 | ir_add_error(ira, param_type_value, |
| ... | ... | @@ -23792,10 +23850,18 @@ static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstru |
| 23792 | 23850 | } |
| 23793 | 23851 | |
| 23794 | 23852 | static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { |
| 23795 | | Error err; |
| 23853 | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); |
| 23854 | result->value.special = ConstValSpecialLazy; |
| 23855 | |
| 23856 | LazyValuePtrType *lazy_ptr_type = allocate<LazyValuePtrType>(1); |
| 23857 | result->value.data.x_lazy = &lazy_ptr_type->base; |
| 23858 | lazy_ptr_type->base.id = LazyValueIdPtrType; |
| 23859 | lazy_ptr_type->base.exec = ira->new_irb.exec; |
| 23860 | |
| 23796 | 23861 | ZigType *child_type = ir_resolve_type(ira, instruction->child_type->child); |
| 23797 | 23862 | if (type_is_invalid(child_type)) |
| 23798 | 23863 | return ira->codegen->invalid_instruction; |
| 23864 | lazy_ptr_type->elem_type = child_type; |
| 23799 | 23865 | |
| 23800 | 23866 | if (child_type->id == ZigTypeIdUnreachable) { |
| 23801 | 23867 | ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); |
| ... | ... | @@ -23817,28 +23883,20 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct |
| 23817 | 23883 | } |
| 23818 | 23884 | } |
| 23819 | 23885 | |
| 23820 | | uint32_t align_bytes; |
| 23821 | 23886 | if (instruction->align_value != nullptr) { |
| 23822 | | if (!ir_resolve_align(ira, instruction->align_value->child, &align_bytes)) |
| 23823 | | return ira->codegen->invalid_instruction; |
| 23824 | | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) |
| 23825 | | return ira->codegen->invalid_instruction; |
| 23826 | | if (!type_has_bits(child_type)) { |
| 23827 | | align_bytes = 0; |
| 23828 | | } |
| 23829 | | } else { |
| 23830 | | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) |
| 23887 | lazy_ptr_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk); |
| 23888 | if (lazy_ptr_type->align_val == nullptr) |
| 23831 | 23889 | return ira->codegen->invalid_instruction; |
| 23832 | | align_bytes = 0; |
| 23833 | 23890 | } |
| 23834 | 23891 | |
| 23835 | | bool allow_zero = instruction->is_allow_zero || instruction->ptr_len == PtrLenC; |
| 23892 | lazy_ptr_type->ptr_len = instruction->ptr_len; |
| 23893 | lazy_ptr_type->is_const = instruction->is_const; |
| 23894 | lazy_ptr_type->is_volatile = instruction->is_volatile; |
| 23895 | lazy_ptr_type->is_allowzero = instruction->is_allow_zero; |
| 23896 | lazy_ptr_type->bit_offset_in_host = instruction->bit_offset_start; |
| 23897 | lazy_ptr_type->host_int_bytes = instruction->host_int_bytes; |
| 23836 | 23898 | |
| 23837 | | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 23838 | | instruction->is_const, instruction->is_volatile, |
| 23839 | | instruction->ptr_len, align_bytes, |
| 23840 | | instruction->bit_offset_start, instruction->host_int_bytes, allow_zero); |
| 23841 | | return ir_const_type(ira, &instruction->base, result_type); |
| 23899 | return result; |
| 23842 | 23900 | } |
| 23843 | 23901 | |
| 23844 | 23902 | static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { |
| ... | ... | @@ -25365,3 +25423,66 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 25365 | 25423 | } |
| 25366 | 25424 | zig_unreachable(); |
| 25367 | 25425 | } |
| 25426 | |
| 25427 | Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { |
| 25428 | Error err; |
| 25429 | if (val->special != ConstValSpecialLazy) |
| 25430 | return ErrorNone; |
| 25431 | IrExecutable *exec = val->data.x_lazy->exec; |
| 25432 | switch (val->data.x_lazy->id) { |
| 25433 | case LazyValueIdInvalid: |
| 25434 | zig_unreachable(); |
| 25435 | case LazyValueIdAlignOf: { |
| 25436 | LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); |
| 25437 | if ((err = type_resolve(codegen, lazy_align_of->target_type, ResolveStatusAlignmentKnown))) |
| 25438 | return err; |
| 25439 | uint64_t align_in_bytes = get_abi_alignment(codegen, lazy_align_of->target_type); |
| 25440 | val->special = ConstValSpecialStatic; |
| 25441 | assert(val->type->id == ZigTypeIdComptimeInt); |
| 25442 | bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); |
| 25443 | return ErrorNone; |
| 25444 | } |
| 25445 | case LazyValueIdSliceType: { |
| 25446 | LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); |
| 25447 | uint32_t align_bytes = 0; |
| 25448 | if (lazy_slice_type->align_val != nullptr) { |
| 25449 | if (!ir_resolve_const_align(codegen, exec, source_node, lazy_slice_type->align_val, &align_bytes)) |
| 25450 | return ErrorSemanticAnalyzeFail; |
| 25451 | } |
| 25452 | ResolveStatus needed_status = (align_bytes == 0) ? |
| 25453 | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; |
| 25454 | if ((err = type_resolve(codegen, lazy_slice_type->elem_type, needed_status))) |
| 25455 | return err; |
| 25456 | ZigType *slice_ptr_type = get_pointer_to_type_extra(codegen, lazy_slice_type->elem_type, |
| 25457 | lazy_slice_type->is_const, lazy_slice_type->is_volatile, PtrLenUnknown, align_bytes, |
| 25458 | 0, 0, lazy_slice_type->is_allowzero); |
| 25459 | val->special = ConstValSpecialStatic; |
| 25460 | assert(val->type->id == ZigTypeIdMetaType); |
| 25461 | val->data.x_type = get_slice_type(codegen, slice_ptr_type); |
| 25462 | return ErrorNone; |
| 25463 | } |
| 25464 | case LazyValueIdPtrType: { |
| 25465 | LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(val->data.x_lazy); |
| 25466 | uint32_t align_bytes = 0; |
| 25467 | if (lazy_ptr_type->align_val != nullptr) { |
| 25468 | if (!ir_resolve_const_align(codegen, exec, source_node, lazy_ptr_type->align_val, &align_bytes)) |
| 25469 | return ErrorSemanticAnalyzeFail; |
| 25470 | } |
| 25471 | ResolveStatus needed_status = (align_bytes == 0) ? |
| 25472 | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; |
| 25473 | if ((err = type_resolve(codegen, lazy_ptr_type->elem_type, needed_status))) |
| 25474 | return err; |
| 25475 | if (!type_has_bits(lazy_ptr_type->elem_type)) |
| 25476 | align_bytes = 0; |
| 25477 | bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; |
| 25478 | assert(val->type->id == ZigTypeIdMetaType); |
| 25479 | val->data.x_type = get_pointer_to_type_extra(codegen, lazy_ptr_type->elem_type, |
| 25480 | lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, |
| 25481 | lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, |
| 25482 | allow_zero); |
| 25483 | val->special = ConstValSpecialStatic; |
| 25484 | return ErrorNone; |
| 25485 | } |
| 25486 | } |
| 25487 | zig_unreachable(); |
| 25488 | } |