| ... | @@ -11058,14 +11058,21 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou | ... | @@ -11058,14 +11058,21 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 11058 | } | 11058 | } |
| 11059 | | 11059 | |
| 11060 | static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, | 11060 | static IrInstruction *ir_analyze_frame_ptr_to_anyframe(IrAnalyze *ira, IrInstruction *source_instr, |
| 11061 | IrInstruction *value, ZigType *wanted_type) | 11061 | IrInstruction *frame_ptr, ZigType *wanted_type) |
| 11062 | { | 11062 | { |
| 11063 | if (instr_is_comptime(value)) { | 11063 | if (instr_is_comptime(frame_ptr)) { |
| 11064 | zig_panic("TODO comptime frame pointer"); | 11064 | ConstExprValue *ptr_val = ir_resolve_const(ira, frame_ptr, UndefBad); |
| | 11065 | if (ptr_val == nullptr) |
| | 11066 | return ira->codegen->invalid_instruction; |
| | 11067 | |
| | 11068 | ir_assert(ptr_val->type->id == ZigTypeIdPointer, source_instr); |
| | 11069 | if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { |
| | 11070 | zig_panic("TODO comptime frame pointer"); |
| | 11071 | } |
| 11065 | } | 11072 | } |
| 11066 | | 11073 | |
| 11067 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, | 11074 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| 11068 | wanted_type, value, CastOpBitCast); | 11075 | wanted_type, frame_ptr, CastOpBitCast); |
| 11069 | result->value.type = wanted_type; | 11076 | result->value.type = wanted_type; |
| 11070 | return result; | 11077 | return result; |
| 11071 | } | 11078 | } |
| ... | @@ -13618,21 +13625,34 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -13618,21 +13625,34 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13618 | if (type_is_invalid(casted_op2->value.type)) | 13625 | if (type_is_invalid(casted_op2->value.type)) |
| 13619 | return ira->codegen->invalid_instruction; | 13626 | return ira->codegen->invalid_instruction; |
| 13620 | | 13627 | |
| 13621 | if (op1->value.special == ConstValSpecialUndef || casted_op2->value.special == ConstValSpecialUndef) { | 13628 | // If either operand is undef, result is undef. |
| 13622 | IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); | 13629 | ConstExprValue *op1_val = nullptr; |
| 13623 | result->value.special = ConstValSpecialUndef; | 13630 | ConstExprValue *op2_val = nullptr; |
| 13624 | return result; | 13631 | if (instr_is_comptime(op1)) { |
| | 13632 | op1_val = ir_resolve_const(ira, op1, UndefOk); |
| | 13633 | if (op1_val == nullptr) |
| | 13634 | return ira->codegen->invalid_instruction; |
| | 13635 | if (op1_val->special == ConstValSpecialUndef) |
| | 13636 | return ir_const_undef(ira, &instruction->base, op1->value.type); |
| 13625 | } | 13637 | } |
| 13626 | if (casted_op2->value.special == ConstValSpecialStatic && op1->value.special == ConstValSpecialStatic && | 13638 | if (instr_is_comptime(casted_op2)) { |
| | 13639 | op2_val = ir_resolve_const(ira, casted_op2, UndefOk); |
| | 13640 | if (op2_val == nullptr) |
| | 13641 | return ira->codegen->invalid_instruction; |
| | 13642 | if (op2_val->special == ConstValSpecialUndef) |
| | 13643 | return ir_const_undef(ira, &instruction->base, op1->value.type); |
| | 13644 | } |
| | 13645 | |
| | 13646 | if (op2_val != nullptr && op1_val != nullptr && |
| 13627 | (op1->value.data.x_ptr.special == ConstPtrSpecialHardCodedAddr || | 13647 | (op1->value.data.x_ptr.special == ConstPtrSpecialHardCodedAddr || |
| 13628 | op1->value.data.x_ptr.special == ConstPtrSpecialNull)) | 13648 | op1->value.data.x_ptr.special == ConstPtrSpecialNull)) |
| 13629 | { | 13649 | { |
| 13630 | uint64_t start_addr = (op1->value.data.x_ptr.special == ConstPtrSpecialNull) ? | 13650 | uint64_t start_addr = (op1_val->data.x_ptr.special == ConstPtrSpecialNull) ? |
| 13631 | 0 : op1->value.data.x_ptr.data.hard_coded_addr.addr; | 13651 | 0 : op1_val->data.x_ptr.data.hard_coded_addr.addr; |
| 13632 | uint64_t elem_offset; | 13652 | uint64_t elem_offset; |
| 13633 | if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) | 13653 | if (!ir_resolve_usize(ira, casted_op2, &elem_offset)) |
| 13634 | return ira->codegen->invalid_instruction; | 13654 | return ira->codegen->invalid_instruction; |
| 13635 | ZigType *elem_type = op1->value.type->data.pointer.child_type; | 13655 | ZigType *elem_type = op1_val->type->data.pointer.child_type; |
| 13636 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) | 13656 | if ((err = type_resolve(ira->codegen, elem_type, ResolveStatusSizeKnown))) |
| 13637 | return ira->codegen->invalid_instruction; | 13657 | return ira->codegen->invalid_instruction; |
| 13638 | uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset; | 13658 | uint64_t byte_offset = type_size(ira->codegen, elem_type) * elem_offset; |
| ... | @@ -13644,7 +13664,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -13644,7 +13664,7 @@ static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 13644 | } else { | 13664 | } else { |
| 13645 | zig_unreachable(); | 13665 | zig_unreachable(); |
| 13646 | } | 13666 | } |
| 13647 | IrInstruction *result = ir_const(ira, &instruction->base, op1->value.type); | 13667 | IrInstruction *result = ir_const(ira, &instruction->base, op1_val->type); |
| 13648 | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; | 13668 | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 13649 | result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; | 13669 | result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar; |
| 13650 | result->value.data.x_ptr.data.hard_coded_addr.addr = new_addr; | 13670 | result->value.data.x_ptr.data.hard_coded_addr.addr = new_addr; |
| ... | @@ -14213,9 +14233,13 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14213,9 +14233,13 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14213 | } | 14233 | } |
| 14214 | break; | 14234 | break; |
| 14215 | case ReqCompTimeNo: | 14235 | case ReqCompTimeNo: |
| 14216 | if (init_val != nullptr) { | 14236 | if (init_val != nullptr && value_is_comptime(init_val)) { |
| 14217 | if (init_val->special == ConstValSpecialStatic && | 14237 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, |
| 14218 | init_val->type->id == ZigTypeIdFn && | 14238 | decl_var_instruction->base.source_node, init_val, UndefOk))) |
| | 14239 | { |
| | 14240 | result_type = ira->codegen->builtin_types.entry_invalid; |
| | 14241 | } else if (init_val->type->id == ZigTypeIdFn && |
| | 14242 | init_val->special != ConstValSpecialUndef && |
| 14219 | init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && | 14243 | init_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 14220 | init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) | 14244 | init_val->data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) |
| 14221 | { | 14245 | { |
| ... | @@ -14273,7 +14297,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14273,7 +14297,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14273 | } | 14297 | } |
| 14274 | } | 14298 | } |
| 14275 | | 14299 | |
| 14276 | if (init_val != nullptr && init_val->special != ConstValSpecialRuntime) { | 14300 | if (init_val != nullptr && value_is_comptime(init_val)) { |
| 14277 | // Resolve ConstPtrMutInfer | 14301 | // Resolve ConstPtrMutInfer |
| 14278 | if (var->gen_is_const) { | 14302 | if (var->gen_is_const) { |
| 14279 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; | 14303 | var_ptr->value.data.x_ptr.mut = ConstPtrMutComptimeConst; |
| ... | @@ -14292,7 +14316,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, | ... | @@ -14292,7 +14316,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, |
| 14292 | ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); | 14316 | ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false); |
| 14293 | } | 14317 | } |
| 14294 | | 14318 | |
| 14295 | if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) { | 14319 | if (instr_is_comptime(var_ptr) && var->mem_slot_index != SIZE_MAX) { |
| 14296 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); | 14320 | assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); |
| 14297 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); | 14321 | ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); |
| 14298 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); | 14322 | copy_const_val(mem_slot, init_val, !is_comptime_var || var->gen_is_const); |
| ... | @@ -15222,7 +15246,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -15222,7 +15246,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 15222 | if (linkage_makes_it_runtime) | 15246 | if (linkage_makes_it_runtime) |
| 15223 | goto no_mem_slot; | 15247 | goto no_mem_slot; |
| 15224 | | 15248 | |
| 15225 | if (var->const_value->special == ConstValSpecialStatic) { | 15249 | if (value_is_comptime(var->const_value)) { |
| 15226 | mem_slot = var->const_value; | 15250 | mem_slot = var->const_value; |
| 15227 | } else { | 15251 | } else { |
| 15228 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { | 15252 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { |
| ... | @@ -19361,7 +19385,10 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct | ... | @@ -19361,7 +19385,10 @@ static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstruct |
| 19361 | ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, | 19385 | ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, |
| 19362 | true, false, PtrLenUnknown, 0, 0, 0, false); | 19386 | true, false, PtrLenUnknown, 0, 0, 0, false); |
| 19363 | ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); | 19387 | ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); |
| 19364 | if (casted_value->value.special == ConstValSpecialStatic) { | 19388 | if (instr_is_comptime(casted_value)) { |
| | 19389 | ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); |
| | 19390 | if (val == nullptr) |
| | 19391 | return ira->codegen->invalid_instruction; |
| 19365 | ErrorTableEntry *err = casted_value->value.data.x_err_set; | 19392 | ErrorTableEntry *err = casted_value->value.data.x_err_set; |
| 19366 | if (!err->cached_error_name_val) { | 19393 | if (!err->cached_error_name_val) { |
| 19367 | ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); | 19394 | ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); |
| ... | @@ -21524,64 +21551,75 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio | ... | @@ -21524,64 +21551,75 @@ static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructio |
| 21524 | return ira->codegen->invalid_instruction; | 21551 | return ira->codegen->invalid_instruction; |
| 21525 | | 21552 | |
| 21526 | // TODO test this at comptime with u8 and non-u8 types | 21553 | // TODO test this at comptime with u8 and non-u8 types |
| 21527 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && | 21554 | if (instr_is_comptime(casted_dest_ptr) && |
| 21528 | casted_byte->value.special == ConstValSpecialStatic && | 21555 | instr_is_comptime(casted_byte) && |
| 21529 | casted_count->value.special == ConstValSpecialStatic && | 21556 | instr_is_comptime(casted_count)) |
| 21530 | casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && | | |
| 21531 | casted_dest_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) | | |
| 21532 | { | 21557 | { |
| 21533 | ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; | 21558 | ConstExprValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); |
| | 21559 | if (dest_ptr_val == nullptr) |
| | 21560 | return ira->codegen->invalid_instruction; |
| 21534 | | 21561 | |
| 21535 | ConstExprValue *dest_elements; | 21562 | ConstExprValue *byte_val = ir_resolve_const(ira, casted_byte, UndefOk); |
| 21536 | size_t start; | 21563 | if (byte_val == nullptr) |
| 21537 | size_t bound_end; | 21564 | return ira->codegen->invalid_instruction; |
| 21538 | switch (dest_ptr_val->data.x_ptr.special) { | | |
| 21539 | case ConstPtrSpecialInvalid: | | |
| 21540 | case ConstPtrSpecialDiscard: | | |
| 21541 | zig_unreachable(); | | |
| 21542 | case ConstPtrSpecialRef: | | |
| 21543 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; | | |
| 21544 | start = 0; | | |
| 21545 | bound_end = 1; | | |
| 21546 | break; | | |
| 21547 | case ConstPtrSpecialBaseArray: | | |
| 21548 | { | | |
| 21549 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; | | |
| 21550 | expand_undef_array(ira->codegen, array_val); | | |
| 21551 | dest_elements = array_val->data.x_array.data.s_none.elements; | | |
| 21552 | start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; | | |
| 21553 | bound_end = array_val->type->data.array.len; | | |
| 21554 | break; | | |
| 21555 | } | | |
| 21556 | case ConstPtrSpecialBaseStruct: | | |
| 21557 | zig_panic("TODO memset on const inner struct"); | | |
| 21558 | case ConstPtrSpecialBaseErrorUnionCode: | | |
| 21559 | zig_panic("TODO memset on const inner error union code"); | | |
| 21560 | case ConstPtrSpecialBaseErrorUnionPayload: | | |
| 21561 | zig_panic("TODO memset on const inner error union payload"); | | |
| 21562 | case ConstPtrSpecialBaseOptionalPayload: | | |
| 21563 | zig_panic("TODO memset on const inner optional payload"); | | |
| 21564 | case ConstPtrSpecialHardCodedAddr: | | |
| 21565 | zig_unreachable(); | | |
| 21566 | case ConstPtrSpecialFunction: | | |
| 21567 | zig_panic("TODO memset on ptr cast from function"); | | |
| 21568 | case ConstPtrSpecialNull: | | |
| 21569 | zig_panic("TODO memset on null ptr"); | | |
| 21570 | } | | |
| 21571 | | 21565 | |
| 21572 | size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); | 21566 | ConstExprValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); |
| 21573 | size_t end = start + count; | 21567 | if (count_val == nullptr) |
| 21574 | if (end > bound_end) { | | |
| 21575 | ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); | | |
| 21576 | return ira->codegen->invalid_instruction; | 21568 | return ira->codegen->invalid_instruction; |
| 21577 | } | | |
| 21578 | | 21569 | |
| 21579 | ConstExprValue *byte_val = &casted_byte->value; | 21570 | if (casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr && |
| 21580 | for (size_t i = start; i < end; i += 1) { | 21571 | casted_dest_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) |
| 21581 | copy_const_val(&dest_elements[i], byte_val, true); | 21572 | { |
| 21582 | } | 21573 | ConstExprValue *dest_elements; |
| | 21574 | size_t start; |
| | 21575 | size_t bound_end; |
| | 21576 | switch (dest_ptr_val->data.x_ptr.special) { |
| | 21577 | case ConstPtrSpecialInvalid: |
| | 21578 | case ConstPtrSpecialDiscard: |
| | 21579 | zig_unreachable(); |
| | 21580 | case ConstPtrSpecialRef: |
| | 21581 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; |
| | 21582 | start = 0; |
| | 21583 | bound_end = 1; |
| | 21584 | break; |
| | 21585 | case ConstPtrSpecialBaseArray: |
| | 21586 | { |
| | 21587 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; |
| | 21588 | expand_undef_array(ira->codegen, array_val); |
| | 21589 | dest_elements = array_val->data.x_array.data.s_none.elements; |
| | 21590 | start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; |
| | 21591 | bound_end = array_val->type->data.array.len; |
| | 21592 | break; |
| | 21593 | } |
| | 21594 | case ConstPtrSpecialBaseStruct: |
| | 21595 | zig_panic("TODO memset on const inner struct"); |
| | 21596 | case ConstPtrSpecialBaseErrorUnionCode: |
| | 21597 | zig_panic("TODO memset on const inner error union code"); |
| | 21598 | case ConstPtrSpecialBaseErrorUnionPayload: |
| | 21599 | zig_panic("TODO memset on const inner error union payload"); |
| | 21600 | case ConstPtrSpecialBaseOptionalPayload: |
| | 21601 | zig_panic("TODO memset on const inner optional payload"); |
| | 21602 | case ConstPtrSpecialHardCodedAddr: |
| | 21603 | zig_unreachable(); |
| | 21604 | case ConstPtrSpecialFunction: |
| | 21605 | zig_panic("TODO memset on ptr cast from function"); |
| | 21606 | case ConstPtrSpecialNull: |
| | 21607 | zig_panic("TODO memset on null ptr"); |
| | 21608 | } |
| 21583 | | 21609 | |
| 21584 | return ir_const_void(ira, &instruction->base); | 21610 | size_t count = bigint_as_unsigned(&count_val->data.x_bigint); |
| | 21611 | size_t end = start + count; |
| | 21612 | if (end > bound_end) { |
| | 21613 | ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); |
| | 21614 | return ira->codegen->invalid_instruction; |
| | 21615 | } |
| | 21616 | |
| | 21617 | for (size_t i = start; i < end; i += 1) { |
| | 21618 | copy_const_val(&dest_elements[i], byte_val, true); |
| | 21619 | } |
| | 21620 | |
| | 21621 | return ir_const_void(ira, &instruction->base); |
| | 21622 | } |
| 21585 | } | 21623 | } |
| 21586 | | 21624 | |
| 21587 | IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, | 21625 | IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| ... | @@ -21649,107 +21687,118 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio | ... | @@ -21649,107 +21687,118 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio |
| 21649 | | 21687 | |
| 21650 | // TODO test this at comptime with u8 and non-u8 types | 21688 | // TODO test this at comptime with u8 and non-u8 types |
| 21651 | // TODO test with dest ptr being a global runtime variable | 21689 | // TODO test with dest ptr being a global runtime variable |
| 21652 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && | 21690 | if (instr_is_comptime(casted_dest_ptr) && |
| 21653 | casted_src_ptr->value.special == ConstValSpecialStatic && | 21691 | instr_is_comptime(casted_src_ptr) && |
| 21654 | casted_count->value.special == ConstValSpecialStatic && | 21692 | instr_is_comptime(casted_count)) |
| 21655 | casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) | | |
| 21656 | { | 21693 | { |
| 21657 | size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); | 21694 | ConstExprValue *dest_ptr_val = ir_resolve_const(ira, casted_dest_ptr, UndefBad); |
| | 21695 | if (dest_ptr_val == nullptr) |
| | 21696 | return ira->codegen->invalid_instruction; |
| 21658 | | 21697 | |
| 21659 | ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; | 21698 | ConstExprValue *src_ptr_val = ir_resolve_const(ira, casted_src_ptr, UndefBad); |
| 21660 | ConstExprValue *dest_elements; | 21699 | if (src_ptr_val == nullptr) |
| 21661 | size_t dest_start; | 21700 | return ira->codegen->invalid_instruction; |
| 21662 | size_t dest_end; | | |
| 21663 | switch (dest_ptr_val->data.x_ptr.special) { | | |
| 21664 | case ConstPtrSpecialInvalid: | | |
| 21665 | case ConstPtrSpecialDiscard: | | |
| 21666 | zig_unreachable(); | | |
| 21667 | case ConstPtrSpecialRef: | | |
| 21668 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; | | |
| 21669 | dest_start = 0; | | |
| 21670 | dest_end = 1; | | |
| 21671 | break; | | |
| 21672 | case ConstPtrSpecialBaseArray: | | |
| 21673 | { | | |
| 21674 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; | | |
| 21675 | expand_undef_array(ira->codegen, array_val); | | |
| 21676 | dest_elements = array_val->data.x_array.data.s_none.elements; | | |
| 21677 | dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; | | |
| 21678 | dest_end = array_val->type->data.array.len; | | |
| 21679 | break; | | |
| 21680 | } | | |
| 21681 | case ConstPtrSpecialBaseStruct: | | |
| 21682 | zig_panic("TODO memcpy on const inner struct"); | | |
| 21683 | case ConstPtrSpecialBaseErrorUnionCode: | | |
| 21684 | zig_panic("TODO memcpy on const inner error union code"); | | |
| 21685 | case ConstPtrSpecialBaseErrorUnionPayload: | | |
| 21686 | zig_panic("TODO memcpy on const inner error union payload"); | | |
| 21687 | case ConstPtrSpecialBaseOptionalPayload: | | |
| 21688 | zig_panic("TODO memcpy on const inner optional payload"); | | |
| 21689 | case ConstPtrSpecialHardCodedAddr: | | |
| 21690 | zig_unreachable(); | | |
| 21691 | case ConstPtrSpecialFunction: | | |
| 21692 | zig_panic("TODO memcpy on ptr cast from function"); | | |
| 21693 | case ConstPtrSpecialNull: | | |
| 21694 | zig_panic("TODO memcpy on null ptr"); | | |
| 21695 | } | | |
| 21696 | | 21701 | |
| 21697 | if (dest_start + count > dest_end) { | 21702 | ConstExprValue *count_val = ir_resolve_const(ira, casted_count, UndefBad); |
| 21698 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); | 21703 | if (count_val == nullptr) |
| 21699 | return ira->codegen->invalid_instruction; | 21704 | return ira->codegen->invalid_instruction; |
| 21700 | } | | |
| 21701 | | 21705 | |
| 21702 | ConstExprValue *src_ptr_val = &casted_src_ptr->value; | 21706 | if (dest_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 21703 | ConstExprValue *src_elements; | 21707 | size_t count = bigint_as_unsigned(&count_val->data.x_bigint); |
| 21704 | size_t src_start; | | |
| 21705 | size_t src_end; | | |
| 21706 | | 21708 | |
| 21707 | switch (src_ptr_val->data.x_ptr.special) { | 21709 | ConstExprValue *dest_elements; |
| 21708 | case ConstPtrSpecialInvalid: | 21710 | size_t dest_start; |
| 21709 | case ConstPtrSpecialDiscard: | 21711 | size_t dest_end; |
| 21710 | zig_unreachable(); | 21712 | switch (dest_ptr_val->data.x_ptr.special) { |
| 21711 | case ConstPtrSpecialRef: | 21713 | case ConstPtrSpecialInvalid: |
| 21712 | src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; | 21714 | case ConstPtrSpecialDiscard: |
| 21713 | src_start = 0; | 21715 | zig_unreachable(); |
| 21714 | src_end = 1; | 21716 | case ConstPtrSpecialRef: |
| 21715 | break; | 21717 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; |
| 21716 | case ConstPtrSpecialBaseArray: | 21718 | dest_start = 0; |
| 21717 | { | 21719 | dest_end = 1; |
| 21718 | ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; | | |
| 21719 | expand_undef_array(ira->codegen, array_val); | | |
| 21720 | src_elements = array_val->data.x_array.data.s_none.elements; | | |
| 21721 | src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; | | |
| 21722 | src_end = array_val->type->data.array.len; | | |
| 21723 | break; | 21720 | break; |
| 21724 | } | 21721 | case ConstPtrSpecialBaseArray: |
| 21725 | case ConstPtrSpecialBaseStruct: | 21722 | { |
| 21726 | zig_panic("TODO memcpy on const inner struct"); | 21723 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; |
| 21727 | case ConstPtrSpecialBaseErrorUnionCode: | 21724 | expand_undef_array(ira->codegen, array_val); |
| 21728 | zig_panic("TODO memcpy on const inner error union code"); | 21725 | dest_elements = array_val->data.x_array.data.s_none.elements; |
| 21729 | case ConstPtrSpecialBaseErrorUnionPayload: | 21726 | dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; |
| 21730 | zig_panic("TODO memcpy on const inner error union payload"); | 21727 | dest_end = array_val->type->data.array.len; |
| 21731 | case ConstPtrSpecialBaseOptionalPayload: | 21728 | break; |
| 21732 | zig_panic("TODO memcpy on const inner optional payload"); | 21729 | } |
| 21733 | case ConstPtrSpecialHardCodedAddr: | 21730 | case ConstPtrSpecialBaseStruct: |
| 21734 | zig_unreachable(); | 21731 | zig_panic("TODO memcpy on const inner struct"); |
| 21735 | case ConstPtrSpecialFunction: | 21732 | case ConstPtrSpecialBaseErrorUnionCode: |
| 21736 | zig_panic("TODO memcpy on ptr cast from function"); | 21733 | zig_panic("TODO memcpy on const inner error union code"); |
| 21737 | case ConstPtrSpecialNull: | 21734 | case ConstPtrSpecialBaseErrorUnionPayload: |
| 21738 | zig_panic("TODO memcpy on null ptr"); | 21735 | zig_panic("TODO memcpy on const inner error union payload"); |
| 21739 | } | 21736 | case ConstPtrSpecialBaseOptionalPayload: |
| | 21737 | zig_panic("TODO memcpy on const inner optional payload"); |
| | 21738 | case ConstPtrSpecialHardCodedAddr: |
| | 21739 | zig_unreachable(); |
| | 21740 | case ConstPtrSpecialFunction: |
| | 21741 | zig_panic("TODO memcpy on ptr cast from function"); |
| | 21742 | case ConstPtrSpecialNull: |
| | 21743 | zig_panic("TODO memcpy on null ptr"); |
| | 21744 | } |
| 21740 | | 21745 | |
| 21741 | if (src_start + count > src_end) { | 21746 | if (dest_start + count > dest_end) { |
| 21742 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); | 21747 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); |
| 21743 | return ira->codegen->invalid_instruction; | 21748 | return ira->codegen->invalid_instruction; |
| 21744 | } | 21749 | } |
| 21745 | | 21750 | |
| 21746 | // TODO check for noalias violations - this should be generalized to work for any function | 21751 | ConstExprValue *src_elements; |
| | 21752 | size_t src_start; |
| | 21753 | size_t src_end; |
| 21747 | | 21754 | |
| 21748 | for (size_t i = 0; i < count; i += 1) { | 21755 | switch (src_ptr_val->data.x_ptr.special) { |
| 21749 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); | 21756 | case ConstPtrSpecialInvalid: |
| 21750 | } | 21757 | case ConstPtrSpecialDiscard: |
| | 21758 | zig_unreachable(); |
| | 21759 | case ConstPtrSpecialRef: |
| | 21760 | src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; |
| | 21761 | src_start = 0; |
| | 21762 | src_end = 1; |
| | 21763 | break; |
| | 21764 | case ConstPtrSpecialBaseArray: |
| | 21765 | { |
| | 21766 | ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; |
| | 21767 | expand_undef_array(ira->codegen, array_val); |
| | 21768 | src_elements = array_val->data.x_array.data.s_none.elements; |
| | 21769 | src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; |
| | 21770 | src_end = array_val->type->data.array.len; |
| | 21771 | break; |
| | 21772 | } |
| | 21773 | case ConstPtrSpecialBaseStruct: |
| | 21774 | zig_panic("TODO memcpy on const inner struct"); |
| | 21775 | case ConstPtrSpecialBaseErrorUnionCode: |
| | 21776 | zig_panic("TODO memcpy on const inner error union code"); |
| | 21777 | case ConstPtrSpecialBaseErrorUnionPayload: |
| | 21778 | zig_panic("TODO memcpy on const inner error union payload"); |
| | 21779 | case ConstPtrSpecialBaseOptionalPayload: |
| | 21780 | zig_panic("TODO memcpy on const inner optional payload"); |
| | 21781 | case ConstPtrSpecialHardCodedAddr: |
| | 21782 | zig_unreachable(); |
| | 21783 | case ConstPtrSpecialFunction: |
| | 21784 | zig_panic("TODO memcpy on ptr cast from function"); |
| | 21785 | case ConstPtrSpecialNull: |
| | 21786 | zig_panic("TODO memcpy on null ptr"); |
| | 21787 | } |
| 21751 | | 21788 | |
| 21752 | return ir_const_void(ira, &instruction->base); | 21789 | if (src_start + count > src_end) { |
| | 21790 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); |
| | 21791 | return ira->codegen->invalid_instruction; |
| | 21792 | } |
| | 21793 | |
| | 21794 | // TODO check for noalias violations - this should be generalized to work for any function |
| | 21795 | |
| | 21796 | for (size_t i = 0; i < count; i += 1) { |
| | 21797 | copy_const_val(&dest_elements[dest_start + i], &src_elements[src_start + i], true); |
| | 21798 | } |
| | 21799 | |
| | 21800 | return ir_const_void(ira, &instruction->base); |
| | 21801 | } |
| 21753 | } | 21802 | } |
| 21754 | | 21803 | |
| 21755 | IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, | 21804 | IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, |
| ... | @@ -22412,13 +22461,26 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr | ... | @@ -22412,13 +22461,26 @@ static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstr |
| 22412 | if (type_is_invalid(casted_result_ptr->value.type)) | 22461 | if (type_is_invalid(casted_result_ptr->value.type)) |
| 22413 | return ira->codegen->invalid_instruction; | 22462 | return ira->codegen->invalid_instruction; |
| 22414 | | 22463 | |
| 22415 | if (casted_op1->value.special == ConstValSpecialStatic && | 22464 | if (instr_is_comptime(casted_op1) && |
| 22416 | casted_op2->value.special == ConstValSpecialStatic && | 22465 | instr_is_comptime(casted_op2) && |
| 22417 | casted_result_ptr->value.special == ConstValSpecialStatic) | 22466 | instr_is_comptime(casted_result_ptr)) |
| 22418 | { | 22467 | { |
| 22419 | BigInt *op1_bigint = &casted_op1->value.data.x_bigint; | 22468 | ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); |
| 22420 | BigInt *op2_bigint = &casted_op2->value.data.x_bigint; | 22469 | if (op1_val == nullptr) |
| 22421 | ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, &casted_result_ptr->value, casted_result_ptr->source_node); | 22470 | return ira->codegen->invalid_instruction; |
| | 22471 | |
| | 22472 | ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); |
| | 22473 | if (op2_val == nullptr) |
| | 22474 | return ira->codegen->invalid_instruction; |
| | 22475 | |
| | 22476 | ConstExprValue *result_val = ir_resolve_const(ira, casted_result_ptr, UndefBad); |
| | 22477 | if (result_val == nullptr) |
| | 22478 | return ira->codegen->invalid_instruction; |
| | 22479 | |
| | 22480 | BigInt *op1_bigint = &op1_val->data.x_bigint; |
| | 22481 | BigInt *op2_bigint = &op2_val->data.x_bigint; |
| | 22482 | ConstExprValue *pointee_val = const_ptr_pointee(ira, ira->codegen, result_val, |
| | 22483 | casted_result_ptr->source_node); |
| 22422 | if (pointee_val == nullptr) | 22484 | if (pointee_val == nullptr) |
| 22423 | return ira->codegen->invalid_instruction; | 22485 | return ira->codegen->invalid_instruction; |
| 22424 | BigInt *dest_bigint = &pointee_val->data.x_bigint; | 22486 | BigInt *dest_bigint = &pointee_val->data.x_bigint; |
| ... | @@ -22839,9 +22901,9 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct | ... | @@ -22839,9 +22901,9 @@ static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstruct |
| 22839 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); | 22901 | return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); |
| 22840 | } else { | 22902 | } else { |
| 22841 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; | 22903 | IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; |
| 22842 | if (type_is_invalid(param_type_value->value.type)) | | |
| 22843 | return ira->codegen->invalid_instruction; | | |
| 22844 | ZigType *param_type = ir_resolve_type(ira, param_type_value); | 22904 | ZigType *param_type = ir_resolve_type(ira, param_type_value); |
| | 22905 | if (type_is_invalid(param_type)) |
| | 22906 | return ira->codegen->invalid_instruction; |
| 22845 | switch (type_requires_comptime(ira->codegen, param_type, nullptr)) { | 22907 | switch (type_requires_comptime(ira->codegen, param_type, nullptr)) { |
| 22846 | case ReqCompTimeYes: | 22908 | case ReqCompTimeYes: |
| 22847 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { | 22909 | if (!calling_convention_allows_zig_types(fn_type_id.cc)) { |
| ... | @@ -23271,7 +23333,12 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -23271,7 +23333,12 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_ |
| 23271 | if (!val) | 23333 | if (!val) |
| 23272 | return ira->codegen->invalid_instruction; | 23334 | return ira->codegen->invalid_instruction; |
| 23273 | | 23335 | |
| 23274 | if (val->special == ConstValSpecialStatic) { | 23336 | if (value_is_comptime(val)) { |
| | 23337 | if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec, |
| | 23338 | source_instr->source_node, val, UndefBad))) |
| | 23339 | { |
| | 23340 | return ira->codegen->invalid_instruction; |
| | 23341 | } |
| 23275 | bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || | 23342 | bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull || |
| 23276 | (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && | 23343 | (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && |
| 23277 | val->data.x_ptr.data.hard_coded_addr.addr == 0); | 23344 | val->data.x_ptr.data.hard_coded_addr.addr == 0); |