| ... | ... | @@ -150,8 +150,10 @@ static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruct |
| 150 | 150 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); |
| 151 | 151 | static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, uint32_t new_align); |
| 152 | 152 | static TypeTableEntry *adjust_slice_align(CodeGen *g, TypeTableEntry *slice_type, uint32_t new_align); |
| 153 | static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); |
| 154 | static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); |
| 153 | 155 | |
| 154 | | ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { |
| 156 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 155 | 157 | assert(get_codegen_ptr_type(const_val->type) != nullptr); |
| 156 | 158 | assert(const_val->special == ConstValSpecialStatic); |
| 157 | 159 | ConstExprValue *result; |
| ... | ... | @@ -181,6 +183,27 @@ ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { |
| 181 | 183 | return result; |
| 182 | 184 | } |
| 183 | 185 | |
| 186 | static bool types_have_same_zig_comptime_repr(TypeTableEntry *a, TypeTableEntry *b) { |
| 187 | if (a == b) |
| 188 | return true; |
| 189 | |
| 190 | if (a->id == b->id) |
| 191 | return true; |
| 192 | |
| 193 | if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) |
| 194 | return true; |
| 195 | |
| 196 | return false; |
| 197 | } |
| 198 | |
| 199 | ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { |
| 200 | ConstExprValue *result = const_ptr_pointee_unchecked(g, const_val); |
| 201 | if (const_val->type->id == TypeTableEntryIdPointer) { |
| 202 | assert(types_have_same_zig_comptime_repr(const_val->type->data.pointer.child_type, result->type)); |
| 203 | } |
| 204 | return result; |
| 205 | } |
| 206 | |
| 184 | 207 | static bool ir_should_inline(IrExecutable *exec, Scope *scope) { |
| 185 | 208 | if (exec->is_inline) |
| 186 | 209 | return true; |
| ... | ... | @@ -7602,6 +7625,19 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, |
| 7602 | 7625 | return ir_add_error_node(ira, source_instruction->source_node, msg); |
| 7603 | 7626 | } |
| 7604 | 7627 | |
| 7628 | static ConstExprValue *ir_const_ptr_pointee(IrAnalyze *ira, ConstExprValue *const_val, AstNode *source_node) { |
| 7629 | ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val); |
| 7630 | assert(val != nullptr); |
| 7631 | assert(const_val->type->id == TypeTableEntryIdPointer); |
| 7632 | TypeTableEntry *expected_type = const_val->type->data.pointer.child_type; |
| 7633 | if (!types_have_same_zig_comptime_repr(val->type, expected_type)) { |
| 7634 | ir_add_error_node(ira, source_node, |
| 7635 | buf_sprintf("TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955")); |
| 7636 | return nullptr; |
| 7637 | } |
| 7638 | return val; |
| 7639 | } |
| 7640 | |
| 7605 | 7641 | static IrInstruction *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) { |
| 7606 | 7642 | IrBasicBlock *bb = exec->basic_block_list.at(0); |
| 7607 | 7643 | for (size_t i = 0; i < bb->instruction_list.length; i += 1) { |
| ... | ... | @@ -9461,7 +9497,9 @@ static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, |
| 9461 | 9497 | wanted_type = adjust_ptr_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment); |
| 9462 | 9498 | |
| 9463 | 9499 | if (instr_is_comptime(value)) { |
| 9464 | | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); |
| 9500 | ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node); |
| 9501 | if (pointee == nullptr) |
| 9502 | return ira->codegen->invalid_instruction; |
| 9465 | 9503 | if (pointee->special != ConstValSpecialRuntime) { |
| 9466 | 9504 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 9467 | 9505 | source_instr->source_node, wanted_type); |
| ... | ... | @@ -9487,7 +9525,9 @@ static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruc |
| 9487 | 9525 | wanted_type = adjust_slice_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment); |
| 9488 | 9526 | |
| 9489 | 9527 | if (instr_is_comptime(value)) { |
| 9490 | | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); |
| 9528 | ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node); |
| 9529 | if (pointee == nullptr) |
| 9530 | return ira->codegen->invalid_instruction; |
| 9491 | 9531 | if (pointee->special != ConstValSpecialRuntime) { |
| 9492 | 9532 | assert(value->value.type->id == TypeTableEntryIdPointer); |
| 9493 | 9533 | TypeTableEntry *array_type = value->value.type->data.pointer.child_type; |
| ... | ... | @@ -10458,7 +10498,9 @@ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *sou |
| 10458 | 10498 | return ira->codegen->invalid_instruction; |
| 10459 | 10499 | |
| 10460 | 10500 | assert(val->type->id == TypeTableEntryIdPointer); |
| 10461 | | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, val); |
| 10501 | ConstExprValue *pointee = ir_const_ptr_pointee(ira, val, source_instr->source_node); |
| 10502 | if (pointee == nullptr) |
| 10503 | return ira->codegen->invalid_instruction; |
| 10462 | 10504 | if (pointee->special != ConstValSpecialRuntime) { |
| 10463 | 10505 | ConstExprValue *array_val = create_const_vals(1); |
| 10464 | 10506 | array_val->special = ConstValSpecialStatic; |
| ... | ... | @@ -10773,6 +10815,8 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10773 | 10815 | !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| 10774 | 10816 | { |
| 10775 | 10817 | IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_child_type); |
| 10818 | if (type_is_invalid(cast1->value.type)) |
| 10819 | return ira->codegen->invalid_instruction; |
| 10776 | 10820 | return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); |
| 10777 | 10821 | } |
| 10778 | 10822 | } |
| ... | ... | @@ -11045,7 +11089,9 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 11045 | 11089 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || |
| 11046 | 11090 | ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) |
| 11047 | 11091 | { |
| 11048 | | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &ptr->value); |
| 11092 | ConstExprValue *pointee = ir_const_ptr_pointee(ira, &ptr->value, source_instruction->source_node); |
| 11093 | if (pointee == nullptr) |
| 11094 | return ira->codegen->invalid_instruction; |
| 11049 | 11095 | if (pointee->special != ConstValSpecialRuntime) { |
| 11050 | 11096 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, |
| 11051 | 11097 | source_instruction->source_node, child_type); |
| ... | ... | @@ -13716,7 +13762,39 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction |
| 13716 | 13762 | } |
| 13717 | 13763 | } |
| 13718 | 13764 | |
| 13765 | // out_val->type must be the type to read the pointer as |
| 13766 | // if the type is different than the actual type then it does a comptime byte reinterpretation |
| 13767 | static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, |
| 13768 | ConstExprValue *out_val, ConstExprValue *ptr_val) |
| 13769 | { |
| 13770 | assert(out_val->type != nullptr); |
| 13771 | |
| 13772 | ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr_val); |
| 13773 | |
| 13774 | size_t src_size = type_size(ira->codegen, pointee->type); |
| 13775 | size_t dst_size = type_size(ira->codegen, out_val->type); |
| 13776 | |
| 13777 | if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { |
| 13778 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 13779 | return ErrorNone; |
| 13780 | } |
| 13781 | |
| 13782 | if (dst_size > src_size) { |
| 13783 | ir_add_error_node(ira, source_node, |
| 13784 | buf_sprintf("attempt to read %zu bytes from pointer to %s which is %zu bytes", |
| 13785 | dst_size, buf_ptr(&pointee->type->name), src_size)); |
| 13786 | return ErrorSemanticAnalyzeFail; |
| 13787 | } |
| 13788 | |
| 13789 | Buf buf = BUF_INIT; |
| 13790 | buf_resize(&buf, src_size); |
| 13791 | buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee); |
| 13792 | buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); |
| 13793 | return ErrorNone; |
| 13794 | } |
| 13795 | |
| 13719 | 13796 | static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { |
| 13797 | Error err; |
| 13720 | 13798 | IrInstruction *value = un_op_instruction->value->other; |
| 13721 | 13799 | |
| 13722 | 13800 | TypeTableEntry *ptr_type = value->value.type; |
| ... | ... | @@ -13746,12 +13824,11 @@ static TypeTableEntry *ir_analyze_dereference(IrAnalyze *ira, IrInstructionUnOp |
| 13746 | 13824 | if (comptime_value == nullptr) |
| 13747 | 13825 | return ira->codegen->builtin_types.entry_invalid; |
| 13748 | 13826 | |
| 13749 | | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, comptime_value); |
| 13750 | | if (pointee->type == child_type) { |
| 13751 | | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); |
| 13752 | | copy_const_val(out_val, pointee, value->value.data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 13753 | | return child_type; |
| 13754 | | } |
| 13827 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); |
| 13828 | out_val->type = child_type; |
| 13829 | if ((err = ir_read_const_ptr(ira, un_op_instruction->base.source_node, out_val, comptime_value))) |
| 13830 | return ira->codegen->builtin_types.entry_invalid; |
| 13831 | return child_type; |
| 13755 | 13832 | } |
| 13756 | 13833 | |
| 13757 | 13834 | ir_build_load_ptr_from(&ira->new_irb, &un_op_instruction->base, value); |
| ... | ... | @@ -14152,7 +14229,10 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 14152 | 14229 | array_type = array_type->data.pointer.child_type; |
| 14153 | 14230 | ptr_type = ptr_type->data.pointer.child_type; |
| 14154 | 14231 | if (orig_array_ptr_val->special != ConstValSpecialRuntime) { |
| 14155 | | orig_array_ptr_val = const_ptr_pointee(ira->codegen, orig_array_ptr_val); |
| 14232 | orig_array_ptr_val = ir_const_ptr_pointee(ira, orig_array_ptr_val, |
| 14233 | elem_ptr_instruction->base.source_node); |
| 14234 | if (orig_array_ptr_val == nullptr) |
| 14235 | return ira->codegen->builtin_types.entry_invalid; |
| 14156 | 14236 | } |
| 14157 | 14237 | } |
| 14158 | 14238 | if (array_type->data.array.len == 0) { |
| ... | ... | @@ -14193,7 +14273,9 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 14193 | 14273 | ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); |
| 14194 | 14274 | if (!ptr_val) |
| 14195 | 14275 | return ira->codegen->builtin_types.entry_invalid; |
| 14196 | | ConstExprValue *args_val = const_ptr_pointee(ira->codegen, ptr_val); |
| 14276 | ConstExprValue *args_val = ir_const_ptr_pointee(ira, ptr_val, elem_ptr_instruction->base.source_node); |
| 14277 | if (args_val == nullptr) |
| 14278 | return ira->codegen->builtin_types.entry_invalid; |
| 14197 | 14279 | size_t start = args_val->data.x_arg_tuple.start_index; |
| 14198 | 14280 | size_t end = args_val->data.x_arg_tuple.end_index; |
| 14199 | 14281 | uint64_t elem_index_val; |
| ... | ... | @@ -14269,120 +14351,126 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 14269 | 14351 | return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); |
| 14270 | 14352 | } |
| 14271 | 14353 | |
| 14272 | | ConstExprValue *array_ptr_val; |
| 14273 | 14354 | if (orig_array_ptr_val->special != ConstValSpecialRuntime && |
| 14274 | | (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) && |
| 14275 | | (array_ptr_val = const_ptr_pointee(ira->codegen, orig_array_ptr_val)) && |
| 14276 | | array_ptr_val->special != ConstValSpecialRuntime && |
| 14277 | | (array_type->id != TypeTableEntryIdPointer || |
| 14278 | | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) |
| 14355 | (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || |
| 14356 | array_type->id == TypeTableEntryIdArray)) |
| 14279 | 14357 | { |
| 14280 | | if (array_type->id == TypeTableEntryIdPointer) { |
| 14281 | | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); |
| 14282 | | out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; |
| 14283 | | size_t new_index; |
| 14284 | | size_t mem_size; |
| 14285 | | size_t old_size; |
| 14286 | | switch (array_ptr_val->data.x_ptr.special) { |
| 14287 | | case ConstPtrSpecialInvalid: |
| 14288 | | case ConstPtrSpecialDiscard: |
| 14289 | | zig_unreachable(); |
| 14290 | | case ConstPtrSpecialRef: |
| 14291 | | mem_size = 1; |
| 14292 | | old_size = 1; |
| 14293 | | new_index = index; |
| 14294 | | |
| 14295 | | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 14296 | | out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; |
| 14297 | | break; |
| 14298 | | case ConstPtrSpecialBaseArray: |
| 14299 | | { |
| 14300 | | size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; |
| 14301 | | new_index = offset + index; |
| 14302 | | mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len; |
| 14303 | | old_size = mem_size - offset; |
| 14304 | | |
| 14305 | | assert(array_ptr_val->data.x_ptr.data.base_array.array_val); |
| 14306 | | |
| 14307 | | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 14308 | | out_val->data.x_ptr.data.base_array.array_val = |
| 14309 | | array_ptr_val->data.x_ptr.data.base_array.array_val; |
| 14310 | | out_val->data.x_ptr.data.base_array.elem_index = new_index; |
| 14311 | | out_val->data.x_ptr.data.base_array.is_cstr = |
| 14312 | | array_ptr_val->data.x_ptr.data.base_array.is_cstr; |
| 14358 | ConstExprValue *array_ptr_val = ir_const_ptr_pointee(ira, orig_array_ptr_val, |
| 14359 | elem_ptr_instruction->base.source_node); |
| 14360 | if (array_ptr_val == nullptr) |
| 14361 | return ira->codegen->builtin_types.entry_invalid; |
| 14313 | 14362 | |
| 14363 | if (array_ptr_val->special != ConstValSpecialRuntime && |
| 14364 | (array_type->id != TypeTableEntryIdPointer || |
| 14365 | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) |
| 14366 | { |
| 14367 | if (array_type->id == TypeTableEntryIdPointer) { |
| 14368 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); |
| 14369 | out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; |
| 14370 | size_t new_index; |
| 14371 | size_t mem_size; |
| 14372 | size_t old_size; |
| 14373 | switch (array_ptr_val->data.x_ptr.special) { |
| 14374 | case ConstPtrSpecialInvalid: |
| 14375 | case ConstPtrSpecialDiscard: |
| 14376 | zig_unreachable(); |
| 14377 | case ConstPtrSpecialRef: |
| 14378 | mem_size = 1; |
| 14379 | old_size = 1; |
| 14380 | new_index = index; |
| 14381 | |
| 14382 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 14383 | out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; |
| 14314 | 14384 | break; |
| 14315 | | } |
| 14316 | | case ConstPtrSpecialBaseStruct: |
| 14317 | | zig_panic("TODO elem ptr on a const inner struct"); |
| 14318 | | case ConstPtrSpecialHardCodedAddr: |
| 14319 | | zig_unreachable(); |
| 14320 | | case ConstPtrSpecialFunction: |
| 14321 | | zig_panic("TODO element ptr of a function casted to a ptr"); |
| 14322 | | } |
| 14323 | | if (new_index >= mem_size) { |
| 14324 | | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, |
| 14325 | | buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); |
| 14326 | | return ira->codegen->builtin_types.entry_invalid; |
| 14327 | | } |
| 14328 | | return return_type; |
| 14329 | | } else if (is_slice(array_type)) { |
| 14330 | | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; |
| 14331 | | if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { |
| 14332 | | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, |
| 14333 | | array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); |
| 14334 | | result->value.type = return_type; |
| 14335 | | ir_link_new_instruction(result, &elem_ptr_instruction->base); |
| 14385 | case ConstPtrSpecialBaseArray: |
| 14386 | { |
| 14387 | size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; |
| 14388 | new_index = offset + index; |
| 14389 | mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len; |
| 14390 | old_size = mem_size - offset; |
| 14391 | |
| 14392 | assert(array_ptr_val->data.x_ptr.data.base_array.array_val); |
| 14393 | |
| 14394 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 14395 | out_val->data.x_ptr.data.base_array.array_val = |
| 14396 | array_ptr_val->data.x_ptr.data.base_array.array_val; |
| 14397 | out_val->data.x_ptr.data.base_array.elem_index = new_index; |
| 14398 | out_val->data.x_ptr.data.base_array.is_cstr = |
| 14399 | array_ptr_val->data.x_ptr.data.base_array.is_cstr; |
| 14400 | |
| 14401 | break; |
| 14402 | } |
| 14403 | case ConstPtrSpecialBaseStruct: |
| 14404 | zig_panic("TODO elem ptr on a const inner struct"); |
| 14405 | case ConstPtrSpecialHardCodedAddr: |
| 14406 | zig_unreachable(); |
| 14407 | case ConstPtrSpecialFunction: |
| 14408 | zig_panic("TODO element ptr of a function casted to a ptr"); |
| 14409 | } |
| 14410 | if (new_index >= mem_size) { |
| 14411 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, |
| 14412 | buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); |
| 14413 | return ira->codegen->builtin_types.entry_invalid; |
| 14414 | } |
| 14336 | 14415 | return return_type; |
| 14337 | | } |
| 14338 | | ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; |
| 14339 | | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); |
| 14340 | | uint64_t slice_len = bigint_as_unsigned(&len_field->data.x_bigint); |
| 14341 | | if (index >= slice_len) { |
| 14342 | | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, |
| 14343 | | buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, |
| 14344 | | index, slice_len)); |
| 14345 | | return ira->codegen->builtin_types.entry_invalid; |
| 14346 | | } |
| 14347 | | out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; |
| 14348 | | switch (ptr_field->data.x_ptr.special) { |
| 14349 | | case ConstPtrSpecialInvalid: |
| 14350 | | case ConstPtrSpecialDiscard: |
| 14351 | | zig_unreachable(); |
| 14352 | | case ConstPtrSpecialRef: |
| 14353 | | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 14354 | | out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; |
| 14355 | | break; |
| 14356 | | case ConstPtrSpecialBaseArray: |
| 14357 | | { |
| 14358 | | size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; |
| 14359 | | uint64_t new_index = offset + index; |
| 14360 | | assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len); |
| 14361 | | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 14362 | | out_val->data.x_ptr.data.base_array.array_val = |
| 14363 | | ptr_field->data.x_ptr.data.base_array.array_val; |
| 14364 | | out_val->data.x_ptr.data.base_array.elem_index = new_index; |
| 14365 | | out_val->data.x_ptr.data.base_array.is_cstr = |
| 14366 | | ptr_field->data.x_ptr.data.base_array.is_cstr; |
| 14416 | } else if (is_slice(array_type)) { |
| 14417 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; |
| 14418 | if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { |
| 14419 | IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, |
| 14420 | array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); |
| 14421 | result->value.type = return_type; |
| 14422 | ir_link_new_instruction(result, &elem_ptr_instruction->base); |
| 14423 | return return_type; |
| 14424 | } |
| 14425 | ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; |
| 14426 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); |
| 14427 | uint64_t slice_len = bigint_as_unsigned(&len_field->data.x_bigint); |
| 14428 | if (index >= slice_len) { |
| 14429 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, |
| 14430 | buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, |
| 14431 | index, slice_len)); |
| 14432 | return ira->codegen->builtin_types.entry_invalid; |
| 14433 | } |
| 14434 | out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; |
| 14435 | switch (ptr_field->data.x_ptr.special) { |
| 14436 | case ConstPtrSpecialInvalid: |
| 14437 | case ConstPtrSpecialDiscard: |
| 14438 | zig_unreachable(); |
| 14439 | case ConstPtrSpecialRef: |
| 14440 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 14441 | out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; |
| 14367 | 14442 | break; |
| 14368 | | } |
| 14369 | | case ConstPtrSpecialBaseStruct: |
| 14370 | | zig_panic("TODO elem ptr on a slice backed by const inner struct"); |
| 14371 | | case ConstPtrSpecialHardCodedAddr: |
| 14372 | | zig_unreachable(); |
| 14373 | | case ConstPtrSpecialFunction: |
| 14374 | | zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); |
| 14443 | case ConstPtrSpecialBaseArray: |
| 14444 | { |
| 14445 | size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; |
| 14446 | uint64_t new_index = offset + index; |
| 14447 | assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len); |
| 14448 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 14449 | out_val->data.x_ptr.data.base_array.array_val = |
| 14450 | ptr_field->data.x_ptr.data.base_array.array_val; |
| 14451 | out_val->data.x_ptr.data.base_array.elem_index = new_index; |
| 14452 | out_val->data.x_ptr.data.base_array.is_cstr = |
| 14453 | ptr_field->data.x_ptr.data.base_array.is_cstr; |
| 14454 | break; |
| 14455 | } |
| 14456 | case ConstPtrSpecialBaseStruct: |
| 14457 | zig_panic("TODO elem ptr on a slice backed by const inner struct"); |
| 14458 | case ConstPtrSpecialHardCodedAddr: |
| 14459 | zig_unreachable(); |
| 14460 | case ConstPtrSpecialFunction: |
| 14461 | zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); |
| 14462 | } |
| 14463 | return return_type; |
| 14464 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 14465 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); |
| 14466 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 14467 | out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; |
| 14468 | out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; |
| 14469 | out_val->data.x_ptr.data.base_array.elem_index = index; |
| 14470 | return return_type; |
| 14471 | } else { |
| 14472 | zig_unreachable(); |
| 14375 | 14473 | } |
| 14376 | | return return_type; |
| 14377 | | } else if (array_type->id == TypeTableEntryIdArray) { |
| 14378 | | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); |
| 14379 | | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 14380 | | out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; |
| 14381 | | out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; |
| 14382 | | out_val->data.x_ptr.data.base_array.elem_index = index; |
| 14383 | | return return_type; |
| 14384 | | } else { |
| 14385 | | zig_unreachable(); |
| 14386 | 14474 | } |
| 14387 | 14475 | } |
| 14388 | 14476 | |
| ... | ... | @@ -14474,7 +14562,9 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 14474 | 14562 | return ira->codegen->invalid_instruction; |
| 14475 | 14563 | |
| 14476 | 14564 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 14477 | | ConstExprValue *struct_val = const_ptr_pointee(ira->codegen, ptr_val); |
| 14565 | ConstExprValue *struct_val = ir_const_ptr_pointee(ira, ptr_val, source_instr->source_node); |
| 14566 | if (struct_val == nullptr) |
| 14567 | return ira->codegen->invalid_instruction; |
| 14478 | 14568 | if (type_is_invalid(struct_val->type)) |
| 14479 | 14569 | return ira->codegen->invalid_instruction; |
| 14480 | 14570 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index]; |
| ... | ... | @@ -14516,7 +14606,9 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_ |
| 14516 | 14606 | return ira->codegen->invalid_instruction; |
| 14517 | 14607 | |
| 14518 | 14608 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 14519 | | ConstExprValue *union_val = const_ptr_pointee(ira->codegen, ptr_val); |
| 14609 | ConstExprValue *union_val = ir_const_ptr_pointee(ira, ptr_val, source_instr->source_node); |
| 14610 | if (union_val == nullptr) |
| 14611 | return ira->codegen->invalid_instruction; |
| 14520 | 14612 | if (type_is_invalid(union_val->type)) |
| 14521 | 14613 | return ira->codegen->invalid_instruction; |
| 14522 | 14614 | |
| ... | ... | @@ -14711,7 +14803,9 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 14711 | 14803 | return ira->codegen->builtin_types.entry_invalid; |
| 14712 | 14804 | |
| 14713 | 14805 | assert(container_ptr->value.type->id == TypeTableEntryIdPointer); |
| 14714 | | ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); |
| 14806 | ConstExprValue *child_val = ir_const_ptr_pointee(ira, container_ptr_val, source_node); |
| 14807 | if (child_val == nullptr) |
| 14808 | return ira->codegen->builtin_types.entry_invalid; |
| 14715 | 14809 | |
| 14716 | 14810 | if (buf_eql_str(field_name, "len")) { |
| 14717 | 14811 | ConstExprValue *len_val = create_const_vals(1); |
| ... | ... | @@ -14735,7 +14829,9 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 14735 | 14829 | return ira->codegen->builtin_types.entry_invalid; |
| 14736 | 14830 | |
| 14737 | 14831 | assert(container_ptr->value.type->id == TypeTableEntryIdPointer); |
| 14738 | | ConstExprValue *child_val = const_ptr_pointee(ira->codegen, container_ptr_val); |
| 14832 | ConstExprValue *child_val = ir_const_ptr_pointee(ira, container_ptr_val, source_node); |
| 14833 | if (child_val == nullptr) |
| 14834 | return ira->codegen->builtin_types.entry_invalid; |
| 14739 | 14835 | TypeTableEntry *child_type = child_val->data.x_type; |
| 14740 | 14836 | |
| 14741 | 14837 | if (type_is_invalid(child_type)) { |
| ... | ... | @@ -15003,7 +15099,10 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 15003 | 15099 | if (!container_ptr_val) |
| 15004 | 15100 | return ira->codegen->builtin_types.entry_invalid; |
| 15005 | 15101 | |
| 15006 | | ConstExprValue *namespace_val = const_ptr_pointee(ira->codegen, container_ptr_val); |
| 15102 | ConstExprValue *namespace_val = ir_const_ptr_pointee(ira, container_ptr_val, |
| 15103 | field_ptr_instruction->base.source_node); |
| 15104 | if (namespace_val == nullptr) |
| 15105 | return ira->codegen->builtin_types.entry_invalid; |
| 15007 | 15106 | assert(namespace_val->special == ConstValSpecialStatic); |
| 15008 | 15107 | |
| 15009 | 15108 | ImportTableEntry *namespace_import = namespace_val->data.x_import; |
| ... | ... | @@ -15079,7 +15178,9 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru |
| 15079 | 15178 | } |
| 15080 | 15179 | if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { |
| 15081 | 15180 | if (instr_is_comptime(casted_value)) { |
| 15082 | | ConstExprValue *dest_val = const_ptr_pointee(ira->codegen, &ptr->value); |
| 15181 | ConstExprValue *dest_val = ir_const_ptr_pointee(ira, &ptr->value, store_ptr_instruction->base.source_node); |
| 15182 | if (dest_val == nullptr) |
| 15183 | return ira->codegen->builtin_types.entry_invalid; |
| 15083 | 15184 | if (dest_val->special != ConstValSpecialRuntime) { |
| 15084 | 15185 | *dest_val = casted_value->value; |
| 15085 | 15186 | if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { |
| ... | ... | @@ -15090,7 +15191,7 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru |
| 15090 | 15191 | } |
| 15091 | 15192 | ir_add_error(ira, &store_ptr_instruction->base, |
| 15092 | 15193 | buf_sprintf("cannot store runtime value in compile time variable")); |
| 15093 | | ConstExprValue *dest_val = const_ptr_pointee(ira->codegen, &ptr->value); |
| 15194 | ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); |
| 15094 | 15195 | dest_val->type = ira->codegen->builtin_types.entry_invalid; |
| 15095 | 15196 | |
| 15096 | 15197 | return ira->codegen->builtin_types.entry_invalid; |
| ... | ... | @@ -15656,7 +15757,9 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira, |
| 15656 | 15757 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); |
| 15657 | 15758 | if (!val) |
| 15658 | 15759 | return ira->codegen->builtin_types.entry_invalid; |
| 15659 | | ConstExprValue *maybe_val = const_ptr_pointee(ira->codegen, val); |
| 15760 | ConstExprValue *maybe_val = ir_const_ptr_pointee(ira, val, unwrap_maybe_instruction->base.source_node); |
| 15761 | if (maybe_val == nullptr) |
| 15762 | return ira->codegen->builtin_types.entry_invalid; |
| 15660 | 15763 | |
| 15661 | 15764 | if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| 15662 | 15765 | if (optional_value_is_null(maybe_val)) { |
| ... | ... | @@ -15947,7 +16050,10 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira, |
| 15947 | 16050 | TypeTableEntry *target_type = target_value_ptr->value.type->data.pointer.child_type; |
| 15948 | 16051 | ConstExprValue *pointee_val = nullptr; |
| 15949 | 16052 | if (instr_is_comptime(target_value_ptr)) { |
| 15950 | | pointee_val = const_ptr_pointee(ira->codegen, &target_value_ptr->value); |
| 16053 | pointee_val = ir_const_ptr_pointee(ira, &target_value_ptr->value, target_value_ptr->source_node); |
| 16054 | if (pointee_val == nullptr) |
| 16055 | return ira->codegen->builtin_types.entry_invalid; |
| 16056 | |
| 15951 | 16057 | if (pointee_val->special == ConstValSpecialRuntime) |
| 15952 | 16058 | pointee_val = nullptr; |
| 15953 | 16059 | } |
| ... | ... | @@ -16078,7 +16184,10 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr |
| 16078 | 16184 | if (!target_value_ptr) |
| 16079 | 16185 | return ira->codegen->builtin_types.entry_invalid; |
| 16080 | 16186 | |
| 16081 | | ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, target_val_ptr); |
| 16187 | ConstExprValue *pointee_val = ir_const_ptr_pointee(ira, target_val_ptr, instruction->base.source_node); |
| 16188 | if (pointee_val == nullptr) |
| 16189 | return ira->codegen->builtin_types.entry_invalid; |
| 16190 | |
| 16082 | 16191 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 16083 | 16192 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 16084 | 16193 | out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; |
| ... | ... | @@ -18815,19 +18924,30 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 18815 | 18924 | if (array_type->id == TypeTableEntryIdPointer) { |
| 18816 | 18925 | TypeTableEntry *child_array_type = array_type->data.pointer.child_type; |
| 18817 | 18926 | assert(child_array_type->id == TypeTableEntryIdArray); |
| 18818 | | parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value); |
| 18819 | | array_val = const_ptr_pointee(ira->codegen, parent_ptr); |
| 18927 | parent_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); |
| 18928 | if (parent_ptr == nullptr) |
| 18929 | return ira->codegen->builtin_types.entry_invalid; |
| 18930 | |
| 18931 | array_val = ir_const_ptr_pointee(ira, parent_ptr, instruction->base.source_node); |
| 18932 | if (array_val == nullptr) |
| 18933 | return ira->codegen->builtin_types.entry_invalid; |
| 18934 | |
| 18820 | 18935 | rel_end = child_array_type->data.array.len; |
| 18821 | 18936 | abs_offset = 0; |
| 18822 | 18937 | } else { |
| 18823 | | array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value); |
| 18938 | array_val = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); |
| 18939 | if (array_val == nullptr) |
| 18940 | return ira->codegen->builtin_types.entry_invalid; |
| 18824 | 18941 | rel_end = array_type->data.array.len; |
| 18825 | 18942 | parent_ptr = nullptr; |
| 18826 | 18943 | abs_offset = 0; |
| 18827 | 18944 | } |
| 18828 | 18945 | } else if (array_type->id == TypeTableEntryIdPointer) { |
| 18829 | 18946 | assert(array_type->data.pointer.ptr_len == PtrLenUnknown); |
| 18830 | | parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value); |
| 18947 | parent_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); |
| 18948 | if (parent_ptr == nullptr) |
| 18949 | return ira->codegen->builtin_types.entry_invalid; |
| 18950 | |
| 18831 | 18951 | if (parent_ptr->special == ConstValSpecialUndef) { |
| 18832 | 18952 | array_val = nullptr; |
| 18833 | 18953 | abs_offset = 0; |
| ... | ... | @@ -18858,7 +18978,10 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 18858 | 18978 | zig_panic("TODO slice of ptr cast from function"); |
| 18859 | 18979 | } |
| 18860 | 18980 | } else if (is_slice(array_type)) { |
| 18861 | | ConstExprValue *slice_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value); |
| 18981 | ConstExprValue *slice_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); |
| 18982 | if (slice_ptr == nullptr) |
| 18983 | return ira->codegen->builtin_types.entry_invalid; |
| 18984 | |
| 18862 | 18985 | parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; |
| 18863 | 18986 | ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index]; |
| 18864 | 18987 | |
| ... | ... | @@ -19258,7 +19381,9 @@ static TypeTableEntry *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInst |
| 19258 | 19381 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 19259 | 19382 | BigInt *op1_bigint = &casted_op1->value.data.x_bigint; |
| 19260 | 19383 | BigInt *op2_bigint = &casted_op2->value.data.x_bigint; |
| 19261 | | ConstExprValue *pointee_val = const_ptr_pointee(ira->codegen, &casted_result_ptr->value); |
| 19384 | ConstExprValue *pointee_val = ir_const_ptr_pointee(ira, &casted_result_ptr->value, casted_result_ptr->source_node); |
| 19385 | if (pointee_val == nullptr) |
| 19386 | return ira->codegen->builtin_types.entry_invalid; |
| 19262 | 19387 | BigInt *dest_bigint = &pointee_val->data.x_bigint; |
| 19263 | 19388 | switch (instruction->op) { |
| 19264 | 19389 | case IrOverflowOpAdd: |
| ... | ... | @@ -19358,7 +19483,9 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, |
| 19358 | 19483 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); |
| 19359 | 19484 | if (!ptr_val) |
| 19360 | 19485 | return ira->codegen->builtin_types.entry_invalid; |
| 19361 | | ConstExprValue *err_union_val = const_ptr_pointee(ira->codegen, ptr_val); |
| 19486 | ConstExprValue *err_union_val = ir_const_ptr_pointee(ira, ptr_val, instruction->base.source_node); |
| 19487 | if (err_union_val == nullptr) |
| 19488 | return ira->codegen->builtin_types.entry_invalid; |
| 19362 | 19489 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 19363 | 19490 | ErrorTableEntry *err = err_union_val->data.x_err_union.err; |
| 19364 | 19491 | assert(err); |
| ... | ... | @@ -19406,7 +19533,9 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 19406 | 19533 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); |
| 19407 | 19534 | if (!ptr_val) |
| 19408 | 19535 | return ira->codegen->builtin_types.entry_invalid; |
| 19409 | | ConstExprValue *err_union_val = const_ptr_pointee(ira->codegen, ptr_val); |
| 19536 | ConstExprValue *err_union_val = ir_const_ptr_pointee(ira, ptr_val, instruction->base.source_node); |
| 19537 | if (err_union_val == nullptr) |
| 19538 | return ira->codegen->builtin_types.entry_invalid; |
| 19410 | 19539 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 19411 | 19540 | ErrorTableEntry *err = err_union_val->data.x_err_union.err; |
| 19412 | 19541 | if (err != nullptr) { |