| ... | ... | @@ -154,7 +154,6 @@ struct ConstCastBadAllowsZero { |
| 154 | 154 | enum UndefAllowed { |
| 155 | 155 | UndefOk, |
| 156 | 156 | UndefBad, |
| 157 | | LazyOk, |
| 158 | 157 | }; |
| 159 | 158 | |
| 160 | 159 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| ... | ... | @@ -10257,57 +10256,32 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio |
| 10257 | 10256 | return const_instr; |
| 10258 | 10257 | } |
| 10259 | 10258 | |
| 10260 | | static Error ir_resolve_const_val(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 10261 | | ConstExprValue *val, UndefAllowed undef_allowed) |
| 10262 | | { |
| 10263 | | Error err; |
| 10264 | | for (;;) { |
| 10265 | | switch (val->special) { |
| 10266 | | case ConstValSpecialStatic: |
| 10267 | | return ErrorNone; |
| 10268 | | case ConstValSpecialRuntime: |
| 10269 | | if (!type_has_bits(val->type)) |
| 10270 | | return ErrorNone; |
| 10271 | | |
| 10272 | | exec_add_error_node(codegen, exec, source_node, |
| 10273 | | buf_sprintf("unable to evaluate constant expression")); |
| 10274 | | return ErrorSemanticAnalyzeFail; |
| 10275 | | case ConstValSpecialUndef: |
| 10276 | | if (undef_allowed == UndefOk) |
| 10277 | | return ErrorNone; |
| 10278 | | |
| 10279 | | exec_add_error_node(codegen, exec, source_node, |
| 10280 | | buf_sprintf("use of undefined value here causes undefined behavior")); |
| 10281 | | return ErrorSemanticAnalyzeFail; |
| 10282 | | case ConstValSpecialLazy: |
| 10283 | | if (undef_allowed == LazyOk) |
| 10284 | | return ErrorNone; |
| 10285 | | |
| 10286 | | if ((err = ir_resolve_lazy(codegen, source_node, val))) |
| 10287 | | return err; |
| 10288 | | |
| 10289 | | continue; |
| 10290 | | } |
| 10291 | | } |
| 10292 | | } |
| 10293 | | |
| 10294 | 10259 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { |
| 10295 | | Error err; |
| 10296 | | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, value->source_node, |
| 10297 | | &value->value, undef_allowed))) |
| 10298 | | { |
| 10299 | | return nullptr; |
| 10260 | switch (value->value.special) { |
| 10261 | case ConstValSpecialStatic: |
| 10262 | return &value->value; |
| 10263 | case ConstValSpecialRuntime: |
| 10264 | if (!type_has_bits(value->value.type)) { |
| 10265 | return &value->value; |
| 10266 | } |
| 10267 | ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); |
| 10268 | return nullptr; |
| 10269 | case ConstValSpecialUndef: |
| 10270 | if (undef_allowed == UndefOk) { |
| 10271 | return &value->value; |
| 10272 | } else { |
| 10273 | ir_add_error(ira, value, buf_sprintf("use of undefined value here causes undefined behavior")); |
| 10274 | return nullptr; |
| 10275 | } |
| 10300 | 10276 | } |
| 10301 | | return &value->value; |
| 10277 | zig_unreachable(); |
| 10302 | 10278 | } |
| 10303 | 10279 | |
| 10304 | 10280 | ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, |
| 10305 | 10281 | ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, |
| 10306 | 10282 | ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, |
| 10307 | | IrExecutable *parent_exec, AstNode *expected_type_source_node, bool allow_lazy) |
| 10283 | IrExecutable *parent_exec, AstNode *expected_type_source_node) |
| 10308 | 10284 | { |
| 10309 | | Error err; |
| 10310 | | |
| 10311 | 10285 | if (expected_type != nullptr && type_is_invalid(expected_type)) |
| 10312 | 10286 | return &codegen->invalid_instruction->value; |
| 10313 | 10287 | |
| ... | ... | @@ -10352,24 +10326,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod |
| 10352 | 10326 | fprintf(stderr, "}\n"); |
| 10353 | 10327 | } |
| 10354 | 10328 | |
| 10355 | | ConstExprValue *result = ir_exec_const_result(codegen, analyzed_executable); |
| 10356 | | |
| 10357 | | if (!allow_lazy) { |
| 10358 | | if ((err = ir_resolve_lazy(codegen, node, result))) |
| 10359 | | return &codegen->invalid_instruction->value; |
| 10360 | | } |
| 10361 | | return result; |
| 10362 | | } |
| 10363 | | |
| 10364 | | static ZigType *ir_resolve_const_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 10365 | | ConstExprValue *val) |
| 10366 | | { |
| 10367 | | Error err; |
| 10368 | | if ((err = ir_resolve_const_val(codegen, exec, source_node, val, UndefBad))) |
| 10369 | | return codegen->builtin_types.entry_invalid; |
| 10370 | | |
| 10371 | | assert(val->data.x_type != nullptr); |
| 10372 | | return val->data.x_type; |
| 10329 | return ir_exec_const_result(codegen, analyzed_executable); |
| 10373 | 10330 | } |
| 10374 | 10331 | |
| 10375 | 10332 | static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| ... | ... | @@ -10382,7 +10339,12 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { |
| 10382 | 10339 | return ira->codegen->builtin_types.entry_invalid; |
| 10383 | 10340 | } |
| 10384 | 10341 | |
| 10385 | | return ir_resolve_const_type(ira->codegen, ira->new_irb.exec, type_value->source_node, &type_value->value); |
| 10342 | ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); |
| 10343 | if (!const_val) |
| 10344 | return ira->codegen->builtin_types.entry_invalid; |
| 10345 | |
| 10346 | assert(const_val->data.x_type != nullptr); |
| 10347 | return const_val->data.x_type; |
| 10386 | 10348 | } |
| 10387 | 10349 | |
| 10388 | 10350 | static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) { |
| ... | ... | @@ -11873,38 +11835,33 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 11873 | 11835 | } |
| 11874 | 11836 | } |
| 11875 | 11837 | |
| 11876 | | static bool ir_resolve_const_align(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 11877 | | ConstExprValue *const_val, uint32_t *out) |
| 11878 | | { |
| 11879 | | Error err; |
| 11880 | | if ((err = ir_resolve_const_val(codegen, exec, source_node, const_val, UndefBad))) |
| 11838 | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { |
| 11839 | if (type_is_invalid(value->value.type)) |
| 11840 | return false; |
| 11841 | |
| 11842 | IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); |
| 11843 | if (type_is_invalid(casted_value->value.type)) |
| 11844 | return false; |
| 11845 | |
| 11846 | ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); |
| 11847 | if (!const_val) |
| 11881 | 11848 | return false; |
| 11882 | 11849 | |
| 11883 | 11850 | uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); |
| 11884 | 11851 | if (align_bytes == 0) { |
| 11885 | | exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment must be >= 1")); |
| 11852 | ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); |
| 11886 | 11853 | return false; |
| 11887 | 11854 | } |
| 11888 | 11855 | |
| 11889 | 11856 | if (!is_power_of_2(align_bytes)) { |
| 11890 | | exec_add_error_node(codegen, exec, source_node, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); |
| 11857 | ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); |
| 11891 | 11858 | return false; |
| 11892 | 11859 | } |
| 11860 | |
| 11893 | 11861 | *out = align_bytes; |
| 11894 | 11862 | return true; |
| 11895 | 11863 | } |
| 11896 | 11864 | |
| 11897 | | static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { |
| 11898 | | if (type_is_invalid(value->value.type)) |
| 11899 | | return false; |
| 11900 | | |
| 11901 | | IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); |
| 11902 | | if (type_is_invalid(casted_value->value.type)) |
| 11903 | | return false; |
| 11904 | | |
| 11905 | | return ir_resolve_const_align(ira->codegen, ira->new_irb.exec, value->source_node, &casted_value->value, out); |
| 11906 | | } |
| 11907 | | |
| 11908 | 11865 | static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { |
| 11909 | 11866 | if (type_is_invalid(value->value.type)) |
| 11910 | 11867 | return false; |
| ... | ... | @@ -12072,140 +12029,6 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 12072 | 12029 | return result; |
| 12073 | 12030 | } |
| 12074 | 12031 | |
| 12075 | | static ZigType *ir_resolve_lazy_fn_type(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, |
| 12076 | | LazyValueFnType *lazy_fn_type) |
| 12077 | | { |
| 12078 | | AstNode *proto_node = lazy_fn_type->proto_node; |
| 12079 | | |
| 12080 | | FnTypeId fn_type_id = {0}; |
| 12081 | | init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); |
| 12082 | | |
| 12083 | | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { |
| 12084 | | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); |
| 12085 | | assert(param_node->type == NodeTypeParamDecl); |
| 12086 | | |
| 12087 | | bool param_is_var_args = param_node->data.param_decl.is_var_args; |
| 12088 | | if (param_is_var_args) { |
| 12089 | | if (fn_type_id.cc == CallingConventionC) { |
| 12090 | | fn_type_id.param_count = fn_type_id.next_param_index; |
| 12091 | | continue; |
| 12092 | | } else if (fn_type_id.cc == CallingConventionUnspecified) { |
| 12093 | | return get_generic_fn_type(codegen, &fn_type_id); |
| 12094 | | } else { |
| 12095 | | zig_unreachable(); |
| 12096 | | } |
| 12097 | | } |
| 12098 | | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; |
| 12099 | | param_info->is_noalias = param_node->data.param_decl.is_noalias; |
| 12100 | | |
| 12101 | | if (lazy_fn_type->param_types[fn_type_id.next_param_index] == nullptr) { |
| 12102 | | param_info->type = nullptr; |
| 12103 | | return get_generic_fn_type(codegen, &fn_type_id); |
| 12104 | | } else { |
| 12105 | | ZigType *param_type = ir_resolve_const_type(codegen, exec, source_node, |
| 12106 | | lazy_fn_type->param_types[fn_type_id.next_param_index]); |
| 12107 | | if (type_is_invalid(param_type)) |
| 12108 | | return nullptr; |
| 12109 | | switch (type_requires_comptime(codegen, param_type)) { |
| 12110 | | case ReqCompTimeYes: |
| 12111 | | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { |
| 12112 | | exec_add_error_node(codegen, exec, source_node, |
| 12113 | | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", |
| 12114 | | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); |
| 12115 | | return nullptr; |
| 12116 | | } |
| 12117 | | param_info->type = param_type; |
| 12118 | | fn_type_id.next_param_index += 1; |
| 12119 | | return get_generic_fn_type(codegen, &fn_type_id); |
| 12120 | | case ReqCompTimeInvalid: |
| 12121 | | return nullptr; |
| 12122 | | case ReqCompTimeNo: |
| 12123 | | break; |
| 12124 | | } |
| 12125 | | if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { |
| 12126 | | exec_add_error_node(codegen, exec, source_node, |
| 12127 | | buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", |
| 12128 | | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); |
| 12129 | | return nullptr; |
| 12130 | | } |
| 12131 | | param_info->type = param_type; |
| 12132 | | } |
| 12133 | | |
| 12134 | | } |
| 12135 | | |
| 12136 | | if (lazy_fn_type->align_val != nullptr) { |
| 12137 | | if (!ir_resolve_const_align(codegen, exec, source_node, lazy_fn_type->align_val, &fn_type_id.alignment)) |
| 12138 | | return nullptr; |
| 12139 | | } |
| 12140 | | |
| 12141 | | fn_type_id.return_type = ir_resolve_const_type(codegen, exec, source_node, lazy_fn_type->return_type); |
| 12142 | | if (type_is_invalid(fn_type_id.return_type)) |
| 12143 | | return nullptr; |
| 12144 | | if (fn_type_id.return_type->id == ZigTypeIdOpaque) { |
| 12145 | | exec_add_error_node(codegen, exec, source_node, |
| 12146 | | buf_sprintf("return type cannot be opaque")); |
| 12147 | | return nullptr; |
| 12148 | | } |
| 12149 | | |
| 12150 | | if (lazy_fn_type->async_allocator_type != nullptr) { |
| 12151 | | fn_type_id.async_allocator_type = ir_resolve_const_type(codegen, exec, source_node, |
| 12152 | | lazy_fn_type->async_allocator_type); |
| 12153 | | if (type_is_invalid(fn_type_id.async_allocator_type)) |
| 12154 | | return nullptr; |
| 12155 | | } |
| 12156 | | |
| 12157 | | return get_fn_type(codegen, &fn_type_id); |
| 12158 | | } |
| 12159 | | |
| 12160 | | Error ir_resolve_lazy(CodeGen *codegen, AstNode *source_node, ConstExprValue *val) { |
| 12161 | | Error err; |
| 12162 | | if (val->special != ConstValSpecialLazy) |
| 12163 | | return ErrorNone; |
| 12164 | | IrExecutable *exec = val->data.x_lazy->exec; |
| 12165 | | switch (val->data.x_lazy->id) { |
| 12166 | | case LazyValueIdInvalid: |
| 12167 | | zig_unreachable(); |
| 12168 | | case LazyValueIdAlignOf: { |
| 12169 | | LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy); |
| 12170 | | if ((err = type_resolve(codegen, lazy_align_of->target_type, ResolveStatusAlignmentKnown))) |
| 12171 | | return err; |
| 12172 | | uint64_t align_in_bytes = get_abi_alignment(codegen, lazy_align_of->target_type); |
| 12173 | | val->special = ConstValSpecialStatic; |
| 12174 | | assert(val->type->id == ZigTypeIdComptimeInt); |
| 12175 | | bigint_init_unsigned(&val->data.x_bigint, align_in_bytes); |
| 12176 | | return ErrorNone; |
| 12177 | | } |
| 12178 | | case LazyValueIdSliceType: { |
| 12179 | | LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(val->data.x_lazy); |
| 12180 | | uint32_t align_bytes = 0; |
| 12181 | | if (lazy_slice_type->align_val != nullptr) { |
| 12182 | | if (!ir_resolve_const_align(codegen, exec, source_node, lazy_slice_type->align_val, &align_bytes)) |
| 12183 | | return ErrorSemanticAnalyzeFail; |
| 12184 | | } |
| 12185 | | if ((err = type_resolve(codegen, lazy_slice_type->elem_type, ResolveStatusZeroBitsKnown))) |
| 12186 | | return err; |
| 12187 | | ZigType *slice_ptr_type = get_pointer_to_type_extra(codegen, lazy_slice_type->elem_type, |
| 12188 | | lazy_slice_type->is_const, lazy_slice_type->is_volatile, PtrLenUnknown, align_bytes, |
| 12189 | | 0, 0, lazy_slice_type->is_allowzero); |
| 12190 | | val->special = ConstValSpecialStatic; |
| 12191 | | assert(val->type->id == ZigTypeIdMetaType); |
| 12192 | | val->data.x_type = get_slice_type(codegen, slice_ptr_type); |
| 12193 | | return ErrorNone; |
| 12194 | | } |
| 12195 | | case LazyValueIdFnType: { |
| 12196 | | ZigType *fn_type = ir_resolve_lazy_fn_type(codegen, exec, source_node, |
| 12197 | | reinterpret_cast<LazyValueFnType *>(val->data.x_lazy)); |
| 12198 | | if (fn_type == nullptr) |
| 12199 | | return ErrorSemanticAnalyzeFail; |
| 12200 | | val->special = ConstValSpecialStatic; |
| 12201 | | assert(val->type->id == ZigTypeIdMetaType); |
| 12202 | | val->data.x_type = fn_type; |
| 12203 | | return ErrorNone; |
| 12204 | | } |
| 12205 | | } |
| 12206 | | zig_unreachable(); |
| 12207 | | } |
| 12208 | | |
| 12209 | 12032 | static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, |
| 12210 | 12033 | IrInstructionAddImplicitReturnType *instruction) |
| 12211 | 12034 | { |
| ... | ... | @@ -14179,7 +14002,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 14179 | 14002 | if (linkage_makes_it_runtime) |
| 14180 | 14003 | goto no_mem_slot; |
| 14181 | 14004 | |
| 14182 | | if (value_is_comptime(var->const_value)) { |
| 14005 | if (var->const_value->special == ConstValSpecialStatic) { |
| 14183 | 14006 | mem_slot = var->const_value; |
| 14184 | 14007 | } else { |
| 14185 | 14008 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { |
| ... | ... | @@ -14197,7 +14020,6 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 14197 | 14020 | case ConstValSpecialRuntime: |
| 14198 | 14021 | goto no_mem_slot; |
| 14199 | 14022 | case ConstValSpecialStatic: // fallthrough |
| 14200 | | case ConstValSpecialLazy: // fallthrough |
| 14201 | 14023 | case ConstValSpecialUndef: { |
| 14202 | 14024 | ConstPtrMut ptr_mut; |
| 14203 | 14025 | if (comptime_var_mem) { |
| ... | ... | @@ -14478,7 +14300,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14478 | 14300 | AstNode *body_node = fn_entry->body_node; |
| 14479 | 14301 | result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, |
| 14480 | 14302 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, |
| 14481 | | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node, false); |
| 14303 | nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec, return_type_node); |
| 14482 | 14304 | |
| 14483 | 14305 | if (inferred_err_set_type != nullptr) { |
| 14484 | 14306 | inferred_err_set_type->data.error_set.infer_fn = nullptr; |
| ... | ... | @@ -14674,8 +14496,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call |
| 14674 | 14496 | ConstExprValue *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, |
| 14675 | 14497 | fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), |
| 14676 | 14498 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, |
| 14677 | | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr, |
| 14678 | | false); |
| 14499 | nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec, nullptr); |
| 14679 | 14500 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 14680 | 14501 | impl_fn->child_scope, fn_proto_node->data.fn_proto.align_expr); |
| 14681 | 14502 | const_instruction->base.value = *align_result; |
| ... | ... | @@ -15808,7 +15629,7 @@ static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 15808 | 15629 | auto entry = container_scope->decl_table.maybe_get(field_name); |
| 15809 | 15630 | Tld *tld = entry ? entry->value : nullptr; |
| 15810 | 15631 | if (tld && tld->id == TldIdFn) { |
| 15811 | | resolve_top_level_decl(ira->codegen, tld, source_instr->source_node, false); |
| 15632 | resolve_top_level_decl(ira->codegen, tld, source_instr->source_node); |
| 15812 | 15633 | if (tld->resolution == TldResolutionInvalid) |
| 15813 | 15634 | return ira->codegen->invalid_instruction; |
| 15814 | 15635 | TldFn *tld_fn = (TldFn *)tld; |
| ... | ... | @@ -15999,7 +15820,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, |
| 15999 | 15820 | |
| 16000 | 15821 | |
| 16001 | 15822 | static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { |
| 16002 | | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node, false); |
| 15823 | resolve_top_level_decl(ira->codegen, tld, source_instruction->source_node); |
| 16003 | 15824 | if (tld->resolution == TldResolutionInvalid) |
| 16004 | 15825 | return ira->codegen->invalid_instruction; |
| 16005 | 15826 | |
| ... | ... | @@ -16655,29 +16476,22 @@ static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, |
| 16655 | 16476 | static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 16656 | 16477 | IrInstructionSliceType *slice_type_instruction) |
| 16657 | 16478 | { |
| 16658 | | IrInstruction *result = ir_const(ira, &slice_type_instruction->base, ira->codegen->builtin_types.entry_type); |
| 16659 | | result->value.special = ConstValSpecialLazy; |
| 16660 | | |
| 16661 | | LazyValueSliceType *lazy_slice_type = allocate<LazyValueSliceType>(1); |
| 16662 | | result->value.data.x_lazy = &lazy_slice_type->base; |
| 16663 | | lazy_slice_type->base.id = LazyValueIdSliceType; |
| 16664 | | lazy_slice_type->base.exec = ira->new_irb.exec; |
| 16665 | | |
| 16479 | Error err; |
| 16480 | uint32_t align_bytes = 0; |
| 16666 | 16481 | if (slice_type_instruction->align_value != nullptr) { |
| 16667 | | lazy_slice_type->align_val = ir_resolve_const(ira, slice_type_instruction->align_value->child, LazyOk); |
| 16668 | | if (lazy_slice_type->align_val == nullptr) |
| 16482 | if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes)) |
| 16669 | 16483 | return ira->codegen->invalid_instruction; |
| 16670 | 16484 | } |
| 16671 | 16485 | |
| 16672 | | lazy_slice_type->elem_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); |
| 16673 | | if (type_is_invalid(lazy_slice_type->elem_type)) |
| 16486 | ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); |
| 16487 | if (type_is_invalid(child_type)) |
| 16674 | 16488 | return ira->codegen->invalid_instruction; |
| 16675 | 16489 | |
| 16676 | | lazy_slice_type->is_const = slice_type_instruction->is_const; |
| 16677 | | lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; |
| 16678 | | lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; |
| 16490 | bool is_const = slice_type_instruction->is_const; |
| 16491 | bool is_volatile = slice_type_instruction->is_volatile; |
| 16492 | bool is_allow_zero = slice_type_instruction->is_allow_zero; |
| 16679 | 16493 | |
| 16680 | | switch (lazy_slice_type->elem_type->id) { |
| 16494 | switch (child_type->id) { |
| 16681 | 16495 | case ZigTypeIdInvalid: // handled above |
| 16682 | 16496 | zig_unreachable(); |
| 16683 | 16497 | case ZigTypeIdUnreachable: |
| ... | ... | @@ -16686,7 +16500,7 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 16686 | 16500 | case ZigTypeIdArgTuple: |
| 16687 | 16501 | case ZigTypeIdOpaque: |
| 16688 | 16502 | ir_add_error_node(ira, slice_type_instruction->base.source_node, |
| 16689 | | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&lazy_slice_type->elem_type->name))); |
| 16503 | buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); |
| 16690 | 16504 | return ira->codegen->invalid_instruction; |
| 16691 | 16505 | case ZigTypeIdMetaType: |
| 16692 | 16506 | case ZigTypeIdVoid: |
| ... | ... | @@ -16708,7 +16522,14 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 16708 | 16522 | case ZigTypeIdBoundFn: |
| 16709 | 16523 | case ZigTypeIdPromise: |
| 16710 | 16524 | case ZigTypeIdVector: |
| 16711 | | return result; |
| 16525 | { |
| 16526 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) |
| 16527 | return ira->codegen->invalid_instruction; |
| 16528 | ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 16529 | is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0, is_allow_zero); |
| 16530 | ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); |
| 16531 | return ir_const_type(ira, &slice_type_instruction->base, result_type); |
| 16532 | } |
| 16712 | 16533 | } |
| 16713 | 16534 | zig_unreachable(); |
| 16714 | 16535 | } |
| ... | ... | @@ -16815,7 +16636,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 16815 | 16636 | case ZigTypeIdPromise: |
| 16816 | 16637 | case ZigTypeIdVector: |
| 16817 | 16638 | { |
| 16818 | | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) |
| 16639 | if ((err = ensure_complete_type(ira->codegen, child_type))) |
| 16819 | 16640 | return ira->codegen->invalid_instruction; |
| 16820 | 16641 | ZigType *result_type = get_array_type(ira->codegen, child_type, size); |
| 16821 | 16642 | return ir_const_type(ira, &array_type_instruction->base, result_type); |
| ... | ... | @@ -18172,7 +17993,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, IrInstruction *source_instr, |
| 18172 | 17993 | while ((curr_entry = decl_it.next()) != nullptr) { |
| 18173 | 17994 | // If the definition is unresolved, force it to be resolved again. |
| 18174 | 17995 | if (curr_entry->value->resolution == TldResolutionUnresolved) { |
| 18175 | | resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false); |
| 17996 | resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node); |
| 18176 | 17997 | if (curr_entry->value->resolution != TldResolutionOk) { |
| 18177 | 17998 | return ErrorSemanticAnalyzeFail; |
| 18178 | 17999 | } |
| ... | ... | @@ -19161,7 +18982,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct |
| 19161 | 18982 | ZigType *void_type = ira->codegen->builtin_types.entry_void; |
| 19162 | 18983 | ConstExprValue *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, |
| 19163 | 18984 | ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, |
| 19164 | | &cimport_scope->buf, block_node, nullptr, nullptr, nullptr, false); |
| 18985 | &cimport_scope->buf, block_node, nullptr, nullptr, nullptr); |
| 19165 | 18986 | if (type_is_invalid(cimport_result->type)) |
| 19166 | 18987 | return ira->codegen->invalid_instruction; |
| 19167 | 18988 | |
| ... | ... | @@ -20708,11 +20529,15 @@ static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructio |
| 20708 | 20529 | } |
| 20709 | 20530 | |
| 20710 | 20531 | static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { |
| 20532 | Error err; |
| 20711 | 20533 | IrInstruction *type_value = instruction->type_value->child; |
| 20712 | 20534 | if (type_is_invalid(type_value->value.type)) |
| 20713 | 20535 | return ira->codegen->invalid_instruction; |
| 20714 | 20536 | ZigType *type_entry = ir_resolve_type(ira, type_value); |
| 20715 | 20537 | |
| 20538 | if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown))) |
| 20539 | return ira->codegen->invalid_instruction; |
| 20540 | |
| 20716 | 20541 | switch (type_entry->id) { |
| 20717 | 20542 | case ZigTypeIdInvalid: |
| 20718 | 20543 | zig_unreachable(); |
| ... | ... | @@ -20744,25 +20569,12 @@ static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstruct |
| 20744 | 20569 | case ZigTypeIdUnion: |
| 20745 | 20570 | case ZigTypeIdFn: |
| 20746 | 20571 | case ZigTypeIdVector: |
| 20747 | | break; |
| 20572 | { |
| 20573 | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); |
| 20574 | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); |
| 20575 | } |
| 20748 | 20576 | } |
| 20749 | | if (type_is_resolved(type_entry, ResolveStatusAlignmentKnown)) { |
| 20750 | | uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); |
| 20751 | | return ir_const_unsigned(ira, &instruction->base, align_in_bytes); |
| 20752 | | } |
| 20753 | | // Here we create a lazy value in order to avoid resolving the alignment of the type |
| 20754 | | // immediately. This avoids false positive dependency loops such as: |
| 20755 | | // const Node = struct { |
| 20756 | | // field: []align(@alignOf(Node)) Node, |
| 20757 | | // }; |
| 20758 | | LazyValueAlignOf *lazy_align_of = allocate<LazyValueAlignOf>(1); |
| 20759 | | lazy_align_of->base.id = LazyValueIdAlignOf; |
| 20760 | | lazy_align_of->base.exec = ira->new_irb.exec; |
| 20761 | | lazy_align_of->target_type = type_entry; |
| 20762 | | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int); |
| 20763 | | result->value.special = ConstValSpecialLazy; |
| 20764 | | result->value.data.x_lazy = &lazy_align_of->base; |
| 20765 | | return result; |
| 20577 | zig_unreachable(); |
| 20766 | 20578 | } |
| 20767 | 20579 | |
| 20768 | 20580 | static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { |
| ... | ... | @@ -21017,77 +20829,96 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 21017 | 20829 | AstNode *proto_node = instruction->base.source_node; |
| 21018 | 20830 | assert(proto_node->type == NodeTypeFnProto); |
| 21019 | 20831 | |
| 21020 | | IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_type); |
| 21021 | | result->value.special = ConstValSpecialLazy; |
| 21022 | | |
| 21023 | | LazyValueFnType *lazy_fn_type = allocate<LazyValueFnType>(1); |
| 21024 | | result->value.data.x_lazy = &lazy_fn_type->base; |
| 21025 | | lazy_fn_type->base.id = LazyValueIdFnType; |
| 21026 | | lazy_fn_type->base.exec = ira->new_irb.exec; |
| 21027 | | |
| 21028 | 20832 | if (proto_node->data.fn_proto.auto_err_set) { |
| 21029 | 20833 | ir_add_error(ira, &instruction->base, |
| 21030 | 20834 | buf_sprintf("inferring error set of return type valid only for function definitions")); |
| 21031 | 20835 | return ira->codegen->invalid_instruction; |
| 21032 | 20836 | } |
| 21033 | 20837 | |
| 21034 | | size_t param_count = proto_node->data.fn_proto.params.length; |
| 21035 | | lazy_fn_type->proto_node = proto_node; |
| 21036 | | lazy_fn_type->param_types = allocate<ConstExprValue *>(param_count); |
| 20838 | FnTypeId fn_type_id = {0}; |
| 20839 | init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); |
| 21037 | 20840 | |
| 21038 | | for (size_t i = 0; i < param_count; i += 1) { |
| 21039 | | AstNode *param_node = proto_node->data.fn_proto.params.at(i); |
| 20841 | for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { |
| 20842 | AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); |
| 21040 | 20843 | assert(param_node->type == NodeTypeParamDecl); |
| 21041 | 20844 | |
| 21042 | 20845 | bool param_is_var_args = param_node->data.param_decl.is_var_args; |
| 21043 | | lazy_fn_type->is_var_args = true; |
| 21044 | 20846 | if (param_is_var_args) { |
| 21045 | | if (proto_node->data.fn_proto.cc == CallingConventionC) { |
| 21046 | | break; |
| 21047 | | } else if (proto_node->data.fn_proto.cc == CallingConventionUnspecified) { |
| 21048 | | lazy_fn_type->is_generic = true; |
| 21049 | | return result; |
| 20847 | if (fn_type_id.cc == CallingConventionC) { |
| 20848 | fn_type_id.param_count = fn_type_id.next_param_index; |
| 20849 | continue; |
| 20850 | } else if (fn_type_id.cc == CallingConventionUnspecified) { |
| 20851 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); |
| 21050 | 20852 | } else { |
| 21051 | 20853 | zig_unreachable(); |
| 21052 | 20854 | } |
| 21053 | 20855 | } |
| 20856 | FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; |
| 20857 | param_info->is_noalias = param_node->data.param_decl.is_noalias; |
| 21054 | 20858 | |
| 21055 | | if (instruction->param_types[i] == nullptr) { |
| 21056 | | lazy_fn_type->is_generic = true; |
| 21057 | | return result; |
| 20859 | if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { |
| 20860 | param_info->type = nullptr; |
| 20861 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); |
| 20862 | } else { |
| 20863 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; |
| 20864 | if (type_is_invalid(param_type_value->value.type)) |
| 20865 | return ira->codegen->invalid_instruction; |
| 20866 | ZigType *param_type = ir_resolve_type(ira, param_type_value); |
| 20867 | switch (type_requires_comptime(ira->codegen, param_type)) { |
| 20868 | case ReqCompTimeYes: |
| 20869 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { |
| 20870 | ir_add_error(ira, param_type_value, |
| 20871 | buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", |
| 20872 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); |
| 20873 | return ira->codegen->invalid_instruction; |
| 20874 | } |
| 20875 | param_info->type = param_type; |
| 20876 | fn_type_id.next_param_index += 1; |
| 20877 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); |
| 20878 | case ReqCompTimeInvalid: |
| 20879 | return ira->codegen->invalid_instruction; |
| 20880 | case ReqCompTimeNo: |
| 20881 | break; |
| 20882 | } |
| 20883 | if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { |
| 20884 | ir_add_error(ira, param_type_value, |
| 20885 | buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", |
| 20886 | buf_ptr(&param_type->name), calling_convention_name(fn_type_id.cc))); |
| 20887 | return ira->codegen->invalid_instruction; |
| 20888 | } |
| 20889 | param_info->type = param_type; |
| 21058 | 20890 | } |
| 21059 | 20891 | |
| 21060 | | IrInstruction *param_type_value = instruction->param_types[i]->child; |
| 21061 | | if (type_is_invalid(param_type_value->value.type)) |
| 21062 | | return ira->codegen->invalid_instruction; |
| 21063 | | ConstExprValue *param_type_val = ir_resolve_const(ira, param_type_value, LazyOk); |
| 21064 | | if (param_type_val == nullptr) |
| 21065 | | return ira->codegen->invalid_instruction; |
| 21066 | | lazy_fn_type->param_types[i] = param_type_val; |
| 21067 | 20892 | } |
| 21068 | 20893 | |
| 21069 | 20894 | if (instruction->align_value != nullptr) { |
| 21070 | | lazy_fn_type->align_val = ir_resolve_const(ira, instruction->align_value->child, LazyOk); |
| 21071 | | if (lazy_fn_type->align_val == nullptr) |
| 20895 | if (!ir_resolve_align(ira, instruction->align_value->child, &fn_type_id.alignment)) |
| 21072 | 20896 | return ira->codegen->invalid_instruction; |
| 21073 | 20897 | } |
| 21074 | 20898 | |
| 21075 | | lazy_fn_type->return_type = ir_resolve_const(ira, instruction->return_type->child, LazyOk); |
| 21076 | | if (lazy_fn_type->return_type == nullptr) |
| 20899 | IrInstruction *return_type_value = instruction->return_type->child; |
| 20900 | fn_type_id.return_type = ir_resolve_type(ira, return_type_value); |
| 20901 | if (type_is_invalid(fn_type_id.return_type)) |
| 21077 | 20902 | return ira->codegen->invalid_instruction; |
| 20903 | if (fn_type_id.return_type->id == ZigTypeIdOpaque) { |
| 20904 | ir_add_error(ira, instruction->return_type, |
| 20905 | buf_sprintf("return type cannot be opaque")); |
| 20906 | return ira->codegen->invalid_instruction; |
| 20907 | } |
| 21078 | 20908 | |
| 21079 | | if (proto_node->data.fn_proto.cc == CallingConventionAsync) { |
| 20909 | if (fn_type_id.cc == CallingConventionAsync) { |
| 21080 | 20910 | if (instruction->async_allocator_type_value == nullptr) { |
| 21081 | 20911 | ir_add_error(ira, &instruction->base, |
| 21082 | 20912 | buf_sprintf("async fn proto missing allocator type")); |
| 21083 | 20913 | return ira->codegen->invalid_instruction; |
| 21084 | 20914 | } |
| 21085 | | lazy_fn_type->async_allocator_type = ir_resolve_const(ira, instruction->async_allocator_type_value->child, LazyOk); |
| 21086 | | if (lazy_fn_type->async_allocator_type == nullptr) |
| 20915 | IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->child; |
| 20916 | fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value); |
| 20917 | if (type_is_invalid(fn_type_id.async_allocator_type)) |
| 21087 | 20918 | return ira->codegen->invalid_instruction; |
| 21088 | 20919 | } |
| 21089 | 20920 | |
| 21090 | | return result; |
| 20921 | return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); |
| 21091 | 20922 | } |
| 21092 | 20923 | |
| 21093 | 20924 | static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { |
| ... | ... | @@ -21756,11 +21587,8 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou |
| 21756 | 21587 | val->type->data.vector.len); |
| 21757 | 21588 | case ZigTypeIdEnum: |
| 21758 | 21589 | switch (val->type->data.enumeration.layout) { |
| 21759 | | case ContainerLayoutAuto: { |
| 21760 | | opt_ir_add_error_node(ira, codegen, source_node, |
| 21761 | | buf_sprintf("compiler bug: TODO: implement enum byte reinterpretation")); |
| 21762 | | return ErrorSemanticAnalyzeFail; |
| 21763 | | } |
| 21590 | case ContainerLayoutAuto: |
| 21591 | zig_panic("TODO buf_read_value_bytes enum auto"); |
| 21764 | 21592 | case ContainerLayoutPacked: |
| 21765 | 21593 | zig_panic("TODO buf_read_value_bytes enum packed"); |
| 21766 | 21594 | case ContainerLayoutExtern: { |
| ... | ... | @@ -22056,7 +21884,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, |
| 22056 | 21884 | Tld *tld = instruction->tld; |
| 22057 | 21885 | LVal lval = instruction->lval; |
| 22058 | 21886 | |
| 22059 | | resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node, true); |
| 21887 | resolve_top_level_decl(ira->codegen, tld, instruction->base.source_node); |
| 22060 | 21888 | if (tld->resolution == TldResolutionInvalid) |
| 22061 | 21889 | return ira->codegen->invalid_instruction; |
| 22062 | 21890 | |