| ... | @@ -64,16 +64,21 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ | ... | @@ -64,16 +64,21 @@ static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, Typ |
| 64 | | 64 | |
| 65 | ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) { | 65 | ConstExprValue *const_ptr_pointee(ConstExprValue *const_val) { |
| 66 | assert(const_val->special == ConstValSpecialStatic); | 66 | assert(const_val->special == ConstValSpecialStatic); |
| 67 | assert(const_val->data.x_ptr.special != ConstPtrSpecialRuntime); | 67 | switch (const_val->data.x_ptr.special) { |
| 68 | ConstExprValue *base_ptr = const_val->data.x_ptr.base_ptr; | 68 | case ConstPtrSpecialInvalid: |
| 69 | size_t index = const_val->data.x_ptr.index; | 69 | zig_unreachable(); |
| 70 | | 70 | case ConstPtrSpecialRef: |
| 71 | if (index == SIZE_MAX) { | 71 | return const_val->data.x_ptr.data.ref.pointee; |
| 72 | return base_ptr; | 72 | case ConstPtrSpecialBaseArray: |
| 73 | } else { | 73 | return &const_val->data.x_ptr.data.base_array.array_val->data.x_array.elements[ |
| 74 | assert(index < base_ptr->data.x_array.size); | 74 | const_val->data.x_ptr.data.base_array.elem_index]; |
| 75 | return &base_ptr->data.x_array.elements[index]; | 75 | case ConstPtrSpecialBaseStruct: |
| | 76 | return &const_val->data.x_ptr.data.base_struct.struct_val->data.x_struct.fields[ |
| | 77 | const_val->data.x_ptr.data.base_struct.field_index]; |
| | 78 | case ConstPtrSpecialHardCodedAddr: |
| | 79 | zig_unreachable(); |
| 76 | } | 80 | } |
| | 81 | zig_unreachable(); |
| 77 | } | 82 | } |
| 78 | | 83 | |
| 79 | static bool ir_should_inline(IrExecutable *exec, Scope *scope) { | 84 | static bool ir_should_inline(IrExecutable *exec, Scope *scope) { |
| ... | @@ -6209,7 +6214,7 @@ static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instructio | ... | @@ -6209,7 +6214,7 @@ static TypeTableEntry *ir_analyze_void(IrAnalyze *ira, IrInstruction *instructio |
| 6209 | | 6214 | |
| 6210 | static TypeTableEntry *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instruction, | 6215 | static TypeTableEntry *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 6211 | ConstExprValue *pointee, TypeTableEntry *pointee_type, | 6216 | ConstExprValue *pointee, TypeTableEntry *pointee_type, |
| 6212 | ConstPtrSpecial special, bool ptr_is_const, bool ptr_is_volatile) | 6217 | bool comptime_var_mem, bool ptr_is_const, bool ptr_is_volatile) |
| 6213 | { | 6218 | { |
| 6214 | if (pointee_type->id == TypeTableEntryIdMetaType) { | 6219 | if (pointee_type->id == TypeTableEntryIdMetaType) { |
| 6215 | TypeTableEntry *type_entry = pointee->data.x_type; | 6220 | TypeTableEntry *type_entry = pointee->data.x_type; |
| ... | @@ -6227,9 +6232,9 @@ static TypeTableEntry *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instr | ... | @@ -6227,9 +6232,9 @@ static TypeTableEntry *ir_analyze_const_ptr(IrAnalyze *ira, IrInstruction *instr |
| 6227 | TypeTableEntry *ptr_type = get_pointer_to_type_volatile(ira->codegen, pointee_type, | 6232 | TypeTableEntry *ptr_type = get_pointer_to_type_volatile(ira->codegen, pointee_type, |
| 6228 | ptr_is_const, ptr_is_volatile); | 6233 | ptr_is_const, ptr_is_volatile); |
| 6229 | ConstExprValue *const_val = ir_build_const_from(ira, instruction); | 6234 | ConstExprValue *const_val = ir_build_const_from(ira, instruction); |
| 6230 | const_val->data.x_ptr.base_ptr = pointee; | 6235 | const_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 6231 | const_val->data.x_ptr.index = SIZE_MAX; | 6236 | const_val->data.x_ptr.comptime_var_mem = comptime_var_mem; |
| 6232 | const_val->data.x_ptr.special = special; | 6237 | const_val->data.x_ptr.data.ref.pointee = pointee; |
| 6233 | return ptr_type; | 6238 | return ptr_type; |
| 6234 | } | 6239 | } |
| 6235 | } | 6240 | } |
| ... | @@ -6471,8 +6476,8 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_ | ... | @@ -6471,8 +6476,8 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_ |
| 6471 | source_instr->scope, source_instr->source_node); | 6476 | source_instr->scope, source_instr->source_node); |
| 6472 | const_instruction->base.value.type = wanted_type; | 6477 | const_instruction->base.value.type = wanted_type; |
| 6473 | const_instruction->base.value.special = ConstValSpecialStatic; | 6478 | const_instruction->base.value.special = ConstValSpecialStatic; |
| 6474 | const_instruction->base.value.data.x_ptr.base_ptr = val; | 6479 | const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialRef; |
| 6475 | const_instruction->base.value.data.x_ptr.index = SIZE_MAX; | 6480 | const_instruction->base.value.data.x_ptr.data.ref.pointee = val; |
| 6476 | return &const_instruction->base; | 6481 | return &const_instruction->base; |
| 6477 | } | 6482 | } |
| 6478 | | 6483 | |
| ... | @@ -6608,10 +6613,10 @@ static IrInstruction *ir_analyze_ptr_to_int(IrAnalyze *ira, IrInstruction *sourc | ... | @@ -6608,10 +6613,10 @@ static IrInstruction *ir_analyze_ptr_to_int(IrAnalyze *ira, IrInstruction *sourc |
| 6608 | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); | 6613 | ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); |
| 6609 | if (!val) | 6614 | if (!val) |
| 6610 | return ira->codegen->invalid_instruction; | 6615 | return ira->codegen->invalid_instruction; |
| 6611 | if (val->data.x_ptr.special == ConstPtrSpecialRuntime) { | 6616 | if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { |
| 6612 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, | 6617 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 6613 | source_instr->source_node, wanted_type); | 6618 | source_instr->source_node, wanted_type); |
| 6614 | bignum_init_unsigned(&result->value.data.x_bignum, val->data.x_ptr.index); | 6619 | bignum_init_unsigned(&result->value.data.x_bignum, val->data.x_ptr.data.hard_coded_addr.addr); |
| 6615 | return result; | 6620 | return result; |
| 6616 | } | 6621 | } |
| 6617 | } | 6622 | } |
| ... | @@ -6633,9 +6638,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc | ... | @@ -6633,9 +6638,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc |
| 6633 | return ira->codegen->invalid_instruction; | 6638 | return ira->codegen->invalid_instruction; |
| 6634 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, | 6639 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 6635 | source_instr->source_node, wanted_type); | 6640 | source_instr->source_node, wanted_type); |
| 6636 | result->value.data.x_ptr.base_ptr = nullptr; | 6641 | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 6637 | result->value.data.x_ptr.index = bignum_to_twos_complement(&val->data.x_bignum); | 6642 | result->value.data.x_ptr.data.hard_coded_addr.addr = bignum_to_twos_complement(&val->data.x_bignum); |
| 6638 | result->value.data.x_ptr.special = ConstPtrSpecialRuntime; | | |
| 6639 | return result; | 6643 | return result; |
| 6640 | } | 6644 | } |
| 6641 | | 6645 | |
| ... | @@ -6660,9 +6664,8 @@ static IrInstruction *ir_analyze_int_lit_to_ptr(IrAnalyze *ira, IrInstruction *s | ... | @@ -6660,9 +6664,8 @@ static IrInstruction *ir_analyze_int_lit_to_ptr(IrAnalyze *ira, IrInstruction *s |
| 6660 | | 6664 | |
| 6661 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, | 6665 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 6662 | source_instr->source_node, wanted_type); | 6666 | source_instr->source_node, wanted_type); |
| 6663 | result->value.data.x_ptr.base_ptr = nullptr; | 6667 | result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; |
| 6664 | result->value.data.x_ptr.index = bignum_to_twos_complement(&val->data.x_bignum); | 6668 | result->value.data.x_ptr.data.hard_coded_addr.addr = bignum_to_twos_complement(&val->data.x_bignum); |
| 6665 | result->value.data.x_ptr.special = ConstPtrSpecialRuntime; | | |
| 6666 | return result; | 6669 | return result; |
| 6667 | } | 6670 | } |
| 6668 | | 6671 | |
| ... | @@ -7006,17 +7009,22 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc | ... | @@ -7006,17 +7009,22 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 7006 | return ira->codegen->invalid_instruction; | 7009 | return ira->codegen->invalid_instruction; |
| 7007 | } else if (type_entry->id == TypeTableEntryIdPointer) { | 7010 | } else if (type_entry->id == TypeTableEntryIdPointer) { |
| 7008 | TypeTableEntry *child_type = type_entry->data.pointer.child_type; | 7011 | TypeTableEntry *child_type = type_entry->data.pointer.child_type; |
| 7009 | if (ptr->value.special != ConstValSpecialRuntime) { | 7012 | if (instr_is_comptime(ptr)) { |
| 7010 | ConstExprValue *pointee = const_ptr_pointee(&ptr->value); | 7013 | // Dereferencing a mutable pointer at compile time is not allowed |
| 7011 | if (pointee->special != ConstValSpecialRuntime) { | 7014 | // unless that pointer is from a comptime variable |
| 7012 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, | 7015 | if (type_entry->data.pointer.is_const || ptr->value.data.x_ptr.comptime_var_mem) { |
| 7013 | source_instruction->source_node, child_type); | 7016 | ConstExprValue *pointee = const_ptr_pointee(&ptr->value); |
| 7014 | result->value = *pointee; | 7017 | if (pointee->special != ConstValSpecialRuntime) { |
| 7015 | return result; | 7018 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, |
| | 7019 | source_instruction->source_node, child_type); |
| | 7020 | result->value = *pointee; |
| | 7021 | return result; |
| | 7022 | } |
| 7016 | } | 7023 | } |
| 7017 | } | 7024 | } |
| 7018 | // TODO if the instruction is a get pointer instruction we can skip it | 7025 | // TODO if the instruction is a const ref instruction we can skip it |
| 7019 | IrInstruction *load_ptr_instruction = ir_build_load_ptr(&ira->new_irb, source_instruction->scope, source_instruction->source_node, ptr); | 7026 | IrInstruction *load_ptr_instruction = ir_build_load_ptr(&ira->new_irb, source_instruction->scope, |
| | 7027 | source_instruction->source_node, ptr); |
| 7020 | load_ptr_instruction->value.type = child_type; | 7028 | load_ptr_instruction->value.type = child_type; |
| 7021 | return load_ptr_instruction; | 7029 | return load_ptr_instruction; |
| 7022 | } else if (type_entry->id == TypeTableEntryIdMetaType) { | 7030 | } else if (type_entry->id == TypeTableEntryIdMetaType) { |
| ... | @@ -7052,8 +7060,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -7052,8 +7060,7 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst |
| 7052 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); | 7060 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); |
| 7053 | if (!val) | 7061 | if (!val) |
| 7054 | return ira->codegen->builtin_types.entry_invalid; | 7062 | return ira->codegen->builtin_types.entry_invalid; |
| 7055 | return ir_analyze_const_ptr(ira, source_instruction, val, value->value.type, | 7063 | return ir_analyze_const_ptr(ira, source_instruction, val, value->value.type, false, is_const, is_volatile); |
| 7056 | ConstPtrSpecialNone, is_const, is_volatile); | | |
| 7057 | } | 7064 | } |
| 7058 | | 7065 | |
| 7059 | TypeTableEntry *ptr_type = get_pointer_to_type_volatile(ira->codegen, value->value.type, is_const, is_volatile); | 7066 | TypeTableEntry *ptr_type = get_pointer_to_type_volatile(ira->codegen, value->value.type, is_const, is_volatile); |
| ... | @@ -7136,13 +7143,14 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { | ... | @@ -7136,13 +7143,14 @@ static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { |
| 7136 | | 7143 | |
| 7137 | ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index]; | 7144 | ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index]; |
| 7138 | ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index]; | 7145 | ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index]; |
| 7139 | ConstExprValue *array_val = ptr_field->data.x_ptr.base_ptr; | 7146 | |
| 7140 | assert(ptr_field->data.x_ptr.index != SIZE_MAX); | 7147 | assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| | 7148 | ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; |
| 7141 | size_t len = len_field->data.x_bignum.data.x_uint; | 7149 | size_t len = len_field->data.x_bignum.data.x_uint; |
| 7142 | Buf *result = buf_alloc(); | 7150 | Buf *result = buf_alloc(); |
| 7143 | buf_resize(result, len); | 7151 | buf_resize(result, len); |
| 7144 | for (size_t i = 0; i < len; i += 1) { | 7152 | for (size_t i = 0; i < len; i += 1) { |
| 7145 | size_t new_index = ptr_field->data.x_ptr.index + i; | 7153 | size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; |
| 7146 | ConstExprValue *char_val = &array_val->data.x_array.elements[new_index]; | 7154 | ConstExprValue *char_val = &array_val->data.x_array.elements[new_index]; |
| 7147 | uint64_t big_c = char_val->data.x_bignum.data.x_uint; | 7155 | uint64_t big_c = char_val->data.x_bignum.data.x_uint; |
| 7148 | assert(big_c <= UINT8_MAX); | 7156 | assert(big_c <= UINT8_MAX); |
| ... | @@ -7591,22 +7599,24 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -7591,22 +7599,24 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * |
| 7591 | child_type = op1_canon_type->data.array.child_type; | 7599 | child_type = op1_canon_type->data.array.child_type; |
| 7592 | op1_array_val = op1_val; | 7600 | op1_array_val = op1_val; |
| 7593 | op1_array_index = 0; | 7601 | op1_array_index = 0; |
| 7594 | op1_array_end = op1_val->data.x_array.size; | 7602 | op1_array_end = op1_canon_type->data.array.len; |
| 7595 | } else if (op1_canon_type->id == TypeTableEntryIdPointer && | 7603 | } else if (op1_canon_type->id == TypeTableEntryIdPointer && |
| 7596 | op1_canon_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && | 7604 | op1_canon_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && |
| 7597 | op1_val->data.x_ptr.special == ConstPtrSpecialCStr) | 7605 | op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray && |
| | 7606 | op1_val->data.x_ptr.data.base_array.is_cstr) |
| 7598 | { | 7607 | { |
| 7599 | child_type = op1_canon_type->data.pointer.child_type; | 7608 | child_type = op1_canon_type->data.pointer.child_type; |
| 7600 | op1_array_val = op1_val->data.x_ptr.base_ptr; | 7609 | op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; |
| 7601 | op1_array_index = op1_val->data.x_ptr.index; | 7610 | op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; |
| 7602 | op1_array_end = op1_array_val->data.x_array.size - 1; | 7611 | op1_array_end = op1_array_val->type->data.array.len - 1; |
| 7603 | } else if (is_slice(op1_canon_type)) { | 7612 | } else if (is_slice(op1_canon_type)) { |
| 7604 | TypeTableEntry *ptr_type = op1_canon_type->data.structure.fields[slice_ptr_index].type_entry; | 7613 | TypeTableEntry *ptr_type = op1_canon_type->data.structure.fields[slice_ptr_index].type_entry; |
| 7605 | child_type = ptr_type->data.pointer.child_type; | 7614 | child_type = ptr_type->data.pointer.child_type; |
| 7606 | ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index]; | 7615 | ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index]; |
| 7607 | op1_array_val = ptr_val->data.x_ptr.base_ptr; | 7616 | assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 7608 | op1_array_index = ptr_val->data.x_ptr.index; | 7617 | op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; |
| 7609 | op1_array_end = op1_array_val->data.x_array.size; | 7618 | op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; |
| | 7619 | op1_array_end = op1_array_val->type->data.array.len; |
| 7610 | } else { | 7620 | } else { |
| 7611 | ir_add_error(ira, op1, | 7621 | ir_add_error(ira, op1, |
| 7612 | buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name))); | 7622 | buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name))); |
| ... | @@ -7626,10 +7636,11 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -7626,10 +7636,11 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * |
| 7626 | } | 7636 | } |
| 7627 | op2_array_val = op2_val; | 7637 | op2_array_val = op2_val; |
| 7628 | op2_array_index = 0; | 7638 | op2_array_index = 0; |
| 7629 | op2_array_end = op2_array_val->data.x_array.size; | 7639 | op2_array_end = op2_array_val->type->data.array.len; |
| 7630 | } else if (op2_canon_type->id == TypeTableEntryIdPointer && | 7640 | } else if (op2_canon_type->id == TypeTableEntryIdPointer && |
| 7631 | op2_canon_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && | 7641 | op2_canon_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && |
| 7632 | op2_val->data.x_ptr.special == ConstPtrSpecialCStr) | 7642 | op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray && |
| | 7643 | op2_val->data.x_ptr.data.base_array.is_cstr) |
| 7633 | { | 7644 | { |
| 7634 | if (child_type != ira->codegen->builtin_types.entry_u8) { | 7645 | if (child_type != ira->codegen->builtin_types.entry_u8) { |
| 7635 | ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", | 7646 | ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", |
| ... | @@ -7637,9 +7648,9 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -7637,9 +7648,9 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * |
| 7637 | buf_ptr(&op2->value.type->name))); | 7648 | buf_ptr(&op2->value.type->name))); |
| 7638 | return ira->codegen->builtin_types.entry_invalid; | 7649 | return ira->codegen->builtin_types.entry_invalid; |
| 7639 | } | 7650 | } |
| 7640 | op2_array_val = op2_val->data.x_ptr.base_ptr; | 7651 | op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; |
| 7641 | op2_array_index = op2_val->data.x_ptr.index; | 7652 | op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; |
| 7642 | op2_array_end = op2_array_val->data.x_array.size - 1; | 7653 | op2_array_end = op2_array_val->type->data.array.len - 1; |
| 7643 | } else if (is_slice(op2_canon_type)) { | 7654 | } else if (is_slice(op2_canon_type)) { |
| 7644 | TypeTableEntry *ptr_type = op2_canon_type->data.structure.fields[slice_ptr_index].type_entry; | 7655 | TypeTableEntry *ptr_type = op2_canon_type->data.structure.fields[slice_ptr_index].type_entry; |
| 7645 | if (ptr_type->data.pointer.child_type != child_type) { | 7656 | if (ptr_type->data.pointer.child_type != child_type) { |
| ... | @@ -7649,9 +7660,10 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -7649,9 +7660,10 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * |
| 7649 | return ira->codegen->builtin_types.entry_invalid; | 7660 | return ira->codegen->builtin_types.entry_invalid; |
| 7650 | } | 7661 | } |
| 7651 | ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index]; | 7662 | ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index]; |
| 7652 | op2_array_val = ptr_val->data.x_ptr.base_ptr; | 7663 | assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); |
| 7653 | op2_array_index = ptr_val->data.x_ptr.index; | 7664 | op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; |
| 7654 | op2_array_end = op2_array_val->data.x_array.size; | 7665 | op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; |
| | 7666 | op2_array_end = op2_array_val->type->data.array.len; |
| 7655 | } else { | 7667 | } else { |
| 7656 | ir_add_error(ira, op2, | 7668 | ir_add_error(ira, op2, |
| 7657 | buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); | 7669 | buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); |
| ... | @@ -7676,12 +7688,12 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -7676,12 +7688,12 @@ static TypeTableEntry *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp * |
| 7676 | out_array_val = allocate<ConstExprValue>(1); | 7688 | out_array_val = allocate<ConstExprValue>(1); |
| 7677 | out_array_val->special = ConstValSpecialStatic; | 7689 | out_array_val->special = ConstValSpecialStatic; |
| 7678 | out_array_val->type = get_array_type(ira->codegen, child_type, new_len); | 7690 | out_array_val->type = get_array_type(ira->codegen, child_type, new_len); |
| 7679 | out_val->data.x_ptr.base_ptr = out_array_val; | 7691 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 7680 | out_val->data.x_ptr.index = 0; | 7692 | out_val->data.x_ptr.data.base_array.is_cstr = true; |
| 7681 | out_val->data.x_ptr.special = ConstPtrSpecialCStr; | 7693 | out_val->data.x_ptr.data.base_array.array_val = out_array_val; |
| | 7694 | out_val->data.x_ptr.data.base_array.elem_index = 0; |
| 7682 | } | 7695 | } |
| 7683 | out_array_val->data.x_array.elements = allocate<ConstExprValue>(new_len); | 7696 | out_array_val->data.x_array.elements = allocate<ConstExprValue>(new_len); |
| 7684 | out_array_val->data.x_array.size = new_len; | | |
| 7685 | | 7697 | |
| 7686 | size_t next_index = 0; | 7698 | size_t next_index = 0; |
| 7687 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { | 7699 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { |
| ... | @@ -7736,7 +7748,6 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -7736,7 +7748,6 @@ static TypeTableEntry *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp |
| 7736 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 7748 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 7737 | | 7749 | |
| 7738 | uint64_t new_array_len = array_len.data.x_uint; | 7750 | uint64_t new_array_len = array_len.data.x_uint; |
| 7739 | out_val->data.x_array.size = new_array_len; | | |
| 7740 | out_val->data.x_array.elements = allocate<ConstExprValue>(new_array_len); | 7751 | out_val->data.x_array.elements = allocate<ConstExprValue>(new_array_len); |
| 7741 | | 7752 | |
| 7742 | uint64_t i = 0; | 7753 | uint64_t i = 0; |
| ... | @@ -8721,24 +8732,23 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -8721,24 +8732,23 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc |
| 8721 | if (var->value.type->id == TypeTableEntryIdInvalid) | 8732 | if (var->value.type->id == TypeTableEntryIdInvalid) |
| 8722 | return var->value.type; | 8733 | return var->value.type; |
| 8723 | | 8734 | |
| 8724 | bool is_comptime = ir_get_var_is_comptime(var); | 8735 | bool comptime_var_mem = ir_get_var_is_comptime(var); |
| 8725 | | 8736 | |
| 8726 | ConstExprValue *mem_slot = nullptr; | 8737 | ConstExprValue *mem_slot = nullptr; |
| 8727 | FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope); | 8738 | FnTableEntry *fn_entry = scope_fn_entry(var->parent_scope); |
| 8728 | if (var->src_is_const && var->value.special == ConstValSpecialStatic) { | 8739 | if (var->value.special == ConstValSpecialStatic) { |
| 8729 | mem_slot = &var->value; | 8740 | mem_slot = &var->value; |
| 8730 | assert(mem_slot->special != ConstValSpecialRuntime); | | |
| 8731 | } else if (fn_entry) { | 8741 | } else if (fn_entry) { |
| 8732 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. | 8742 | // TODO once the analyze code is fully ported over to IR we won't need this SIZE_MAX thing. |
| 8733 | if (var->mem_slot_index != SIZE_MAX && (is_comptime || var->gen_is_const)) | 8743 | if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) |
| 8734 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; | 8744 | mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index]; |
| 8735 | } | 8745 | } |
| 8736 | | 8746 | |
| 8737 | bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; | 8747 | bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const; |
| 8738 | bool is_volatile = (var->value.type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false; | 8748 | bool is_volatile = (var->value.type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false; |
| 8739 | if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { | 8749 | if (mem_slot && mem_slot->special != ConstValSpecialRuntime) { |
| 8740 | ConstPtrSpecial ptr_special = is_comptime ? ConstPtrSpecialInline : ConstPtrSpecialNone; | 8750 | return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type, |
| 8741 | return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type, ptr_special, is_const, is_volatile); | 8751 | comptime_var_mem, is_const, is_volatile); |
| 8742 | } else { | 8752 | } else { |
| 8743 | ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile); | 8753 | ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile); |
| 8744 | type_ensure_zero_bits_known(ira->codegen, var->value.type); | 8754 | type_ensure_zero_bits_known(ira->codegen, var->value.type); |
| ... | @@ -8793,7 +8803,8 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -8793,7 +8803,8 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 8793 | buf_sprintf("index 0 outside array of size 0")); | 8803 | buf_sprintf("index 0 outside array of size 0")); |
| 8794 | } | 8804 | } |
| 8795 | TypeTableEntry *child_type = array_type->data.array.child_type; | 8805 | TypeTableEntry *child_type = array_type->data.array.child_type; |
| 8796 | return_type = get_pointer_to_type(ira->codegen, child_type, false); | 8806 | return_type = get_pointer_to_type_volatile(ira->codegen, child_type, |
| | 8807 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile); |
| 8797 | } else if (array_type->id == TypeTableEntryIdPointer) { | 8808 | } else if (array_type->id == TypeTableEntryIdPointer) { |
| 8798 | return_type = array_type; | 8809 | return_type = array_type; |
| 8799 | } else if (is_slice(array_type)) { | 8810 | } else if (is_slice(array_type)) { |
| ... | @@ -8826,8 +8837,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -8826,8 +8837,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 8826 | is_const, is_volatile); | 8837 | is_const, is_volatile); |
| 8827 | } else { | 8838 | } else { |
| 8828 | return ir_analyze_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val, | 8839 | return ir_analyze_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val, |
| 8829 | ira->codegen->builtin_types.entry_void, ConstPtrSpecialNone, | 8840 | ira->codegen->builtin_types.entry_void, false, is_const, is_volatile); |
| 8830 | is_const, is_volatile); | | |
| 8831 | } | 8841 | } |
| 8832 | } else { | 8842 | } else { |
| 8833 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, | 8843 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, |
| ... | @@ -8858,30 +8868,54 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -8858,30 +8868,54 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 8858 | if (array_ptr->value.special != ConstValSpecialRuntime && | 8868 | if (array_ptr->value.special != ConstValSpecialRuntime && |
| 8859 | (array_ptr_val = const_ptr_pointee(&array_ptr->value)) && | 8869 | (array_ptr_val = const_ptr_pointee(&array_ptr->value)) && |
| 8860 | array_ptr_val->special != ConstValSpecialRuntime && | 8870 | array_ptr_val->special != ConstValSpecialRuntime && |
| 8861 | (array_type->id != TypeTableEntryIdPointer || array_ptr_val->data.x_ptr.special != ConstPtrSpecialRuntime)) | 8871 | (array_type->id != TypeTableEntryIdPointer || |
| | 8872 | array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) |
| 8862 | { | 8873 | { |
| 8863 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); | 8874 | ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base); |
| | 8875 | out_val->data.x_ptr.comptime_var_mem = array_ptr->value.data.x_ptr.comptime_var_mem; |
| 8864 | if (array_type->id == TypeTableEntryIdPointer) { | 8876 | if (array_type->id == TypeTableEntryIdPointer) { |
| 8865 | size_t offset = array_ptr_val->data.x_ptr.index; | | |
| 8866 | size_t new_index; | 8877 | size_t new_index; |
| 8867 | size_t mem_size; | 8878 | size_t mem_size; |
| 8868 | size_t old_size; | 8879 | size_t old_size; |
| 8869 | if (offset == SIZE_MAX) { | 8880 | switch (array_ptr_val->data.x_ptr.special) { |
| 8870 | new_index = SIZE_MAX; | 8881 | case ConstPtrSpecialInvalid: |
| 8871 | mem_size = 1; | 8882 | zig_unreachable(); |
| 8872 | old_size = 1; | 8883 | case ConstPtrSpecialRef: |
| 8873 | } else { | 8884 | mem_size = 1; |
| 8874 | new_index = offset + index; | 8885 | old_size = 1; |
| 8875 | mem_size = array_ptr_val->data.x_ptr.base_ptr->data.x_array.size; | 8886 | new_index = index; |
| 8876 | old_size = mem_size - offset; | 8887 | |
| | 8888 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| | 8889 | out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; |
| | 8890 | break; |
| | 8891 | case ConstPtrSpecialBaseArray: |
| | 8892 | { |
| | 8893 | size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; |
| | 8894 | new_index = offset + index; |
| | 8895 | mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len; |
| | 8896 | old_size = mem_size - offset; |
| | 8897 | |
| | 8898 | assert(array_ptr_val->data.x_ptr.data.base_array.array_val); |
| | 8899 | |
| | 8900 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| | 8901 | out_val->data.x_ptr.data.base_array.array_val = |
| | 8902 | array_ptr_val->data.x_ptr.data.base_array.array_val; |
| | 8903 | out_val->data.x_ptr.data.base_array.elem_index = new_index; |
| | 8904 | out_val->data.x_ptr.data.base_array.is_cstr = |
| | 8905 | array_ptr_val->data.x_ptr.data.base_array.is_cstr; |
| | 8906 | |
| | 8907 | break; |
| | 8908 | } |
| | 8909 | case ConstPtrSpecialBaseStruct: |
| | 8910 | zig_panic("TODO elem ptr on a const inner struct"); |
| | 8911 | case ConstPtrSpecialHardCodedAddr: |
| | 8912 | zig_unreachable(); |
| 8877 | } | 8913 | } |
| 8878 | if (new_index >= mem_size) { | 8914 | if (new_index >= mem_size) { |
| 8879 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, | 8915 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, |
| 8880 | buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, index, old_size)); | 8916 | buf_sprintf("index %" PRIu64 " outside pointer of size %" PRIu64, index, old_size)); |
| 8881 | return ira->codegen->builtin_types.entry_invalid; | 8917 | return ira->codegen->builtin_types.entry_invalid; |
| 8882 | } | 8918 | } |
| 8883 | out_val->data.x_ptr.base_ptr = array_ptr_val->data.x_ptr.base_ptr; | | |
| 8884 | out_val->data.x_ptr.index = new_index; | | |
| 8885 | } else if (is_slice(array_type)) { | 8919 | } else if (is_slice(array_type)) { |
| 8886 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; | 8920 | ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; |
| 8887 | ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; | 8921 | ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; |
| ... | @@ -8892,18 +8926,35 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc | ... | @@ -8892,18 +8926,35 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc |
| 8892 | index, slice_len)); | 8926 | index, slice_len)); |
| 8893 | return ira->codegen->builtin_types.entry_invalid; | 8927 | return ira->codegen->builtin_types.entry_invalid; |
| 8894 | } | 8928 | } |
| 8895 | out_val->data.x_ptr.base_ptr = ptr_field->data.x_ptr.base_ptr; | 8929 | switch (ptr_field->data.x_ptr.special) { |
| 8896 | size_t offset = ptr_field->data.x_ptr.index; | 8930 | case ConstPtrSpecialInvalid: |
| 8897 | if (offset == SIZE_MAX) { | 8931 | zig_unreachable(); |
| 8898 | out_val->data.x_ptr.index = SIZE_MAX; | 8932 | case ConstPtrSpecialRef: |
| 8899 | } else { | 8933 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 8900 | uint64_t new_index = offset + index; | 8934 | out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; |
| 8901 | assert(new_index < ptr_field->data.x_ptr.base_ptr->data.x_array.size); | 8935 | break; |
| 8902 | out_val->data.x_ptr.index = new_index; | 8936 | case ConstPtrSpecialBaseArray: |
| | 8937 | { |
| | 8938 | size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; |
| | 8939 | uint64_t new_index = offset + index; |
| | 8940 | assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len); |
| | 8941 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| | 8942 | out_val->data.x_ptr.data.base_array.array_val = |
| | 8943 | ptr_field->data.x_ptr.data.base_array.array_val; |
| | 8944 | out_val->data.x_ptr.data.base_array.elem_index = new_index; |
| | 8945 | out_val->data.x_ptr.data.base_array.is_cstr = |
| | 8946 | ptr_field->data.x_ptr.data.base_array.is_cstr; |
| | 8947 | break; |
| | 8948 | } |
| | 8949 | case ConstPtrSpecialBaseStruct: |
| | 8950 | zig_panic("TODO elem ptr on a slice backed by const inner struct"); |
| | 8951 | case ConstPtrSpecialHardCodedAddr: |
| | 8952 | zig_unreachable(); |
| 8903 | } | 8953 | } |
| 8904 | } else if (array_type->id == TypeTableEntryIdArray) { | 8954 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 8905 | out_val->data.x_ptr.base_ptr = array_ptr_val; | 8955 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 8906 | out_val->data.x_ptr.index = index; | 8956 | out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; |
| | 8957 | out_val->data.x_ptr.data.base_array.elem_index = index; |
| 8907 | } else { | 8958 | } else { |
| 8908 | zig_unreachable(); | 8959 | zig_unreachable(); |
| 8909 | } | 8960 | } |
| ... | @@ -8931,6 +8982,9 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, | ... | @@ -8931,6 +8982,9 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 8931 | return ira->codegen->builtin_types.entry_invalid; | 8982 | return ira->codegen->builtin_types.entry_invalid; |
| 8932 | TldFn *tld_fn = (TldFn *)tld; | 8983 | TldFn *tld_fn = (TldFn *)tld; |
| 8933 | FnTableEntry *fn_entry = tld_fn->fn_entry; | 8984 | FnTableEntry *fn_entry = tld_fn->fn_entry; |
| | 8985 | if (fn_entry->type_entry->id == TypeTableEntryIdInvalid) |
| | 8986 | return ira->codegen->builtin_types.entry_invalid; |
| | 8987 | |
| 8934 | IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, field_ptr_instruction->base.scope, | 8988 | IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, field_ptr_instruction->base.scope, |
| 8935 | field_ptr_instruction->base.source_node, fn_entry, container_ptr); | 8989 | field_ptr_instruction->base.source_node, fn_entry, container_ptr); |
| 8936 | return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value, true, false); | 8990 | return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value, true, false); |
| ... | @@ -8962,15 +9016,17 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field | ... | @@ -8962,15 +9016,17 @@ static TypeTableEntry *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field |
| 8962 | if (!ptr_val) | 9016 | if (!ptr_val) |
| 8963 | return ira->codegen->builtin_types.entry_invalid; | 9017 | return ira->codegen->builtin_types.entry_invalid; |
| 8964 | | 9018 | |
| 8965 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialRuntime) { | 9019 | if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 8966 | ConstExprValue *struct_val = const_ptr_pointee(ptr_val); | 9020 | ConstExprValue *struct_val = const_ptr_pointee(ptr_val); |
| 8967 | if (value_is_comptime(struct_val)) { | 9021 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index]; |
| 8968 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index]; | 9022 | TypeTableEntry *ptr_type = get_pointer_to_type_volatile(ira->codegen, field_val->type, |
| 8969 | if (value_is_comptime(field_val)) { | 9023 | is_const, is_volatile); |
| 8970 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, field_val, | 9024 | ConstExprValue *const_val = ir_build_const_from(ira, &field_ptr_instruction->base); |
| 8971 | field_val->type, ConstPtrSpecialNone, is_const, is_volatile); | 9025 | const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; |
| 8972 | } | 9026 | const_val->data.x_ptr.comptime_var_mem = container_ptr->value.data.x_ptr.comptime_var_mem; |
| 8973 | } | 9027 | const_val->data.x_ptr.data.base_struct.struct_val = struct_val; |
| | 9028 | const_val->data.x_ptr.data.base_struct.field_index = field->src_index; |
| | 9029 | return ptr_type; |
| 8974 | } | 9030 | } |
| 8975 | } | 9031 | } |
| 8976 | ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field); | 9032 | ir_build_struct_field_ptr_from(&ira->new_irb, &field_ptr_instruction->base, container_ptr, field); |
| ... | @@ -9032,7 +9088,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source | ... | @@ -9032,7 +9088,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source |
| 9032 | bool ptr_is_const = true; | 9088 | bool ptr_is_const = true; |
| 9033 | bool ptr_is_volatile = false; | 9089 | bool ptr_is_volatile = false; |
| 9034 | return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, | 9090 | return ir_analyze_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, |
| 9035 | ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9091 | false, ptr_is_const, ptr_is_volatile); |
| 9036 | } | 9092 | } |
| 9037 | case TldIdTypeDef: | 9093 | case TldIdTypeDef: |
| 9038 | { | 9094 | { |
| ... | @@ -9049,7 +9105,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source | ... | @@ -9049,7 +9105,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source |
| 9049 | bool ptr_is_const = true; | 9105 | bool ptr_is_const = true; |
| 9050 | bool ptr_is_volatile = false; | 9106 | bool ptr_is_volatile = false; |
| 9051 | return ir_analyze_const_ptr(ira, source_instruction, const_val, ira->codegen->builtin_types.entry_type, | 9107 | return ir_analyze_const_ptr(ira, source_instruction, const_val, ira->codegen->builtin_types.entry_type, |
| 9052 | ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9108 | false, ptr_is_const, ptr_is_volatile); |
| 9053 | } | 9109 | } |
| 9054 | } | 9110 | } |
| 9055 | zig_unreachable(); | 9111 | zig_unreachable(); |
| ... | @@ -9092,7 +9148,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -9092,7 +9148,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 9092 | bool ptr_is_const = true; | 9148 | bool ptr_is_const = true; |
| 9093 | bool ptr_is_volatile = false; | 9149 | bool ptr_is_volatile = false; |
| 9094 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, len_val, | 9150 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, len_val, |
| 9095 | usize, ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9151 | usize, false, ptr_is_const, ptr_is_volatile); |
| 9096 | } else { | 9152 | } else { |
| 9097 | ir_add_error_node(ira, source_node, | 9153 | ir_add_error_node(ira, source_node, |
| 9098 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), | 9154 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), |
| ... | @@ -9116,7 +9172,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -9116,7 +9172,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 9116 | bool ptr_is_const = true; | 9172 | bool ptr_is_const = true; |
| 9117 | bool ptr_is_volatile = false; | 9173 | bool ptr_is_volatile = false; |
| 9118 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, len_val, | 9174 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, len_val, |
| 9119 | usize, ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9175 | usize, false, ptr_is_const, ptr_is_volatile); |
| 9120 | } else { | 9176 | } else { |
| 9121 | ir_add_error_node(ira, source_node, | 9177 | ir_add_error_node(ira, source_node, |
| 9122 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), | 9178 | buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), |
| ... | @@ -9155,14 +9211,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -9155,14 +9211,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 9155 | bool ptr_is_volatile = false; | 9211 | bool ptr_is_volatile = false; |
| 9156 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, | 9212 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, |
| 9157 | create_const_enum_tag(child_type, field->value), child_type, | 9213 | create_const_enum_tag(child_type, field->value), child_type, |
| 9158 | ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9214 | false, ptr_is_const, ptr_is_volatile); |
| 9159 | } else { | 9215 | } else { |
| 9160 | bool ptr_is_const = true; | 9216 | bool ptr_is_const = true; |
| 9161 | bool ptr_is_volatile = false; | 9217 | bool ptr_is_volatile = false; |
| 9162 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, | 9218 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, |
| 9163 | create_const_unsigned_negative(child_type->data.enumeration.tag_type, field->value, false), | 9219 | create_const_unsigned_negative(child_type->data.enumeration.tag_type, field->value, false), |
| 9164 | child_type->data.enumeration.tag_type, | 9220 | child_type->data.enumeration.tag_type, |
| 9165 | ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9221 | false, ptr_is_const, ptr_is_volatile); |
| 9166 | } | 9222 | } |
| 9167 | } | 9223 | } |
| 9168 | } | 9224 | } |
| ... | @@ -9187,7 +9243,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -9187,7 +9243,7 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 9187 | bool ptr_is_const = true; | 9243 | bool ptr_is_const = true; |
| 9188 | bool ptr_is_volatile = false; | 9244 | bool ptr_is_volatile = false; |
| 9189 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, const_val, | 9245 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, const_val, |
| 9190 | child_type, ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9246 | child_type, false, ptr_is_const, ptr_is_volatile); |
| 9191 | } | 9247 | } |
| 9192 | | 9248 | |
| 9193 | ir_add_error(ira, &field_ptr_instruction->base, | 9249 | ir_add_error(ira, &field_ptr_instruction->base, |
| ... | @@ -9201,14 +9257,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru | ... | @@ -9201,14 +9257,14 @@ static TypeTableEntry *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstru |
| 9201 | create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, | 9257 | create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, |
| 9202 | child_type->data.integral.bit_count, false), | 9258 | child_type->data.integral.bit_count, false), |
| 9203 | ira->codegen->builtin_types.entry_num_lit_int, | 9259 | ira->codegen->builtin_types.entry_num_lit_int, |
| 9204 | ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9260 | false, ptr_is_const, ptr_is_volatile); |
| 9205 | } else if (buf_eql_str(field_name, "is_signed")) { | 9261 | } else if (buf_eql_str(field_name, "is_signed")) { |
| 9206 | bool ptr_is_const = true; | 9262 | bool ptr_is_const = true; |
| 9207 | bool ptr_is_volatile = false; | 9263 | bool ptr_is_volatile = false; |
| 9208 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, | 9264 | return ir_analyze_const_ptr(ira, &field_ptr_instruction->base, |
| 9209 | create_const_bool(ira->codegen, child_type->data.integral.is_signed), | 9265 | create_const_bool(ira->codegen, child_type->data.integral.is_signed), |
| 9210 | ira->codegen->builtin_types.entry_bool, | 9266 | ira->codegen->builtin_types.entry_bool, |
| 9211 | ConstPtrSpecialNone, ptr_is_const, ptr_is_volatile); | 9267 | false, ptr_is_const, ptr_is_volatile); |
| 9212 | } else { | 9268 | } else { |
| 9213 | ir_add_error(ira, &field_ptr_instruction->base, | 9269 | ir_add_error(ira, &field_ptr_instruction->base, |
| 9214 | buf_sprintf("type '%s' has no member called '%s'", | 9270 | buf_sprintf("type '%s' has no member called '%s'", |
| ... | @@ -9295,16 +9351,16 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru | ... | @@ -9295,16 +9351,16 @@ static TypeTableEntry *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstru |
| 9295 | if (casted_value == ira->codegen->invalid_instruction) | 9351 | if (casted_value == ira->codegen->invalid_instruction) |
| 9296 | return ira->codegen->builtin_types.entry_invalid; | 9352 | return ira->codegen->builtin_types.entry_invalid; |
| 9297 | | 9353 | |
| 9298 | if (ptr->value.special != ConstValSpecialRuntime && ptr->value.data.x_ptr.special != ConstPtrSpecialRuntime) { | 9354 | if (instr_is_comptime(ptr) && ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 9299 | bool is_inline = (ptr->value.data.x_ptr.special == ConstPtrSpecialInline); | 9355 | bool comptime_var_mem = ptr->value.data.x_ptr.comptime_var_mem; |
| 9300 | if (casted_value->value.special != ConstValSpecialRuntime) { | 9356 | if (comptime_var_mem) { |
| 9301 | ConstExprValue *dest_val = const_ptr_pointee(&ptr->value); | 9357 | if (instr_is_comptime(casted_value)) { |
| 9302 | if (dest_val->special != ConstValSpecialRuntime) { | 9358 | ConstExprValue *dest_val = const_ptr_pointee(&ptr->value); |
| 9303 | *dest_val = casted_value->value; | 9359 | if (dest_val->special != ConstValSpecialRuntime) { |
| 9304 | return ir_analyze_void(ira, &store_ptr_instruction->base); | 9360 | *dest_val = casted_value->value; |
| | 9361 | return ir_analyze_void(ira, &store_ptr_instruction->base); |
| | 9362 | } |
| 9305 | } | 9363 | } |
| 9306 | } | | |
| 9307 | if (is_inline) { | | |
| 9308 | ir_add_error(ira, &store_ptr_instruction->base, | 9364 | ir_add_error(ira, &store_ptr_instruction->base, |
| 9309 | buf_sprintf("cannot store runtime value in compile time variable")); | 9365 | buf_sprintf("cannot store runtime value in compile time variable")); |
| 9310 | return ira->codegen->builtin_types.entry_invalid; | 9366 | return ira->codegen->builtin_types.entry_invalid; |
| ... | @@ -9906,14 +9962,15 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira, | ... | @@ -9906,14 +9962,15 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira, |
| 9906 | return ira->codegen->builtin_types.entry_invalid; | 9962 | return ira->codegen->builtin_types.entry_invalid; |
| 9907 | } | 9963 | } |
| 9908 | TypeTableEntry *child_type = type_entry->data.maybe.child_type; | 9964 | TypeTableEntry *child_type = type_entry->data.maybe.child_type; |
| 9909 | TypeTableEntry *result_type = get_pointer_to_type(ira->codegen, child_type, false); | 9965 | TypeTableEntry *result_type = get_pointer_to_type_volatile(ira->codegen, child_type, |
| | 9966 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile); |
| 9910 | | 9967 | |
| 9911 | if (instr_is_comptime(value)) { | 9968 | if (instr_is_comptime(value)) { |
| 9912 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); | 9969 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); |
| 9913 | if (!val) | 9970 | if (!val) |
| 9914 | return ira->codegen->builtin_types.entry_invalid; | 9971 | return ira->codegen->builtin_types.entry_invalid; |
| 9915 | ConstExprValue *maybe_val = val->data.x_ptr.base_ptr; | 9972 | assert(val->data.x_ptr.special == ConstPtrSpecialRef); |
| 9916 | assert(val->data.x_ptr.index == SIZE_MAX); | 9973 | ConstExprValue *maybe_val = val->data.x_ptr.data.ref.pointee; |
| 9917 | | 9974 | |
| 9918 | if (maybe_val->special != ConstValSpecialRuntime) { | 9975 | if (maybe_val->special != ConstValSpecialRuntime) { |
| 9919 | if (!maybe_val->data.x_maybe) { | 9976 | if (!maybe_val->data.x_maybe) { |
| ... | @@ -9921,8 +9978,8 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira, | ... | @@ -9921,8 +9978,8 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira, |
| 9921 | return ira->codegen->builtin_types.entry_invalid; | 9978 | return ira->codegen->builtin_types.entry_invalid; |
| 9922 | } | 9979 | } |
| 9923 | ConstExprValue *out_val = ir_build_const_from(ira, &unwrap_maybe_instruction->base); | 9980 | ConstExprValue *out_val = ir_build_const_from(ira, &unwrap_maybe_instruction->base); |
| 9924 | out_val->data.x_ptr.base_ptr = maybe_val->data.x_maybe; | 9981 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 9925 | out_val->data.x_ptr.index = SIZE_MAX; | 9982 | out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_maybe; |
| 9926 | return result_type; | 9983 | return result_type; |
| 9927 | } | 9984 | } |
| 9928 | } | 9985 | } |
| ... | @@ -10215,9 +10272,10 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr | ... | @@ -10215,9 +10272,10 @@ static TypeTableEntry *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstr |
| 10215 | ConstExprValue *pointee_val = const_ptr_pointee(target_val_ptr); | 10272 | ConstExprValue *pointee_val = const_ptr_pointee(target_val_ptr); |
| 10216 | if (pointee_val->type->id == TypeTableEntryIdEnum) { | 10273 | if (pointee_val->type->id == TypeTableEntryIdEnum) { |
| 10217 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 10274 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 10218 | out_val->data.x_ptr.base_ptr = pointee_val->data.x_enum.payload; | 10275 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 10219 | out_val->data.x_ptr.index = SIZE_MAX; | 10276 | out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_enum.payload; |
| 10220 | return get_pointer_to_type(ira->codegen, pointee_val->type, target_value_ptr->value.type->data.pointer.is_const); | 10277 | return get_pointer_to_type(ira->codegen, pointee_val->type, |
| | 10278 | target_value_ptr->value.type->data.pointer.is_const); |
| 10221 | } else { | 10279 | } else { |
| 10222 | zig_panic("TODO comptime switch var"); | 10280 | zig_panic("TODO comptime switch var"); |
| 10223 | } | 10281 | } |
| ... | @@ -10501,7 +10559,6 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira | ... | @@ -10501,7 +10559,6 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira |
| 10501 | const_val.special = ConstValSpecialStatic; | 10559 | const_val.special = ConstValSpecialStatic; |
| 10502 | const_val.type = fixed_size_array_type; | 10560 | const_val.type = fixed_size_array_type; |
| 10503 | const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count); | 10561 | const_val.data.x_array.elements = allocate<ConstExprValue>(elem_count); |
| 10504 | const_val.data.x_array.size = elem_count; | | |
| 10505 | | 10562 | |
| 10506 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); | 10563 | bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); |
| 10507 | | 10564 | |
| ... | @@ -10540,8 +10597,9 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira | ... | @@ -10540,8 +10597,9 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira |
| 10540 | for (size_t i = 0; i < elem_count; i += 1) { | 10597 | for (size_t i = 0; i < elem_count; i += 1) { |
| 10541 | ConstExprValue *elem_val = &out_val->data.x_array.elements[i]; | 10598 | ConstExprValue *elem_val = &out_val->data.x_array.elements[i]; |
| 10542 | if (elem_val->type->id == TypeTableEntryIdArray) { | 10599 | if (elem_val->type->id == TypeTableEntryIdArray) { |
| 10543 | elem_val->data.x_array.parent_array = out_val; | 10600 | elem_val->data.x_array.parent.id = ConstParentIdArray; |
| 10544 | elem_val->data.x_array.parent_array_index = i; | 10601 | elem_val->data.x_array.parent.data.p_array.array_val = out_val; |
| | 10602 | elem_val->data.x_array.parent.data.p_array.elem_index = i; |
| 10545 | } | 10603 | } |
| 10546 | } | 10604 | } |
| 10547 | return fixed_size_array_type; | 10605 | return fixed_size_array_type; |
| ... | @@ -11227,22 +11285,34 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi | ... | @@ -11227,22 +11285,34 @@ static TypeTableEntry *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructi |
| 11227 | | 11285 | |
| 11228 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && | 11286 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && |
| 11229 | casted_byte->value.special == ConstValSpecialStatic && | 11287 | casted_byte->value.special == ConstValSpecialStatic && |
| 11230 | casted_count->value.special == ConstValSpecialStatic) | 11288 | casted_count->value.special == ConstValSpecialStatic && |
| | 11289 | casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) |
| 11231 | { | 11290 | { |
| 11232 | ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; | 11291 | ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; |
| 11233 | | 11292 | |
| 11234 | ConstExprValue *dest_elements; | 11293 | ConstExprValue *dest_elements; |
| 11235 | size_t start; | 11294 | size_t start; |
| 11236 | size_t bound_end; | 11295 | size_t bound_end; |
| 11237 | if (dest_ptr_val->data.x_ptr.index == SIZE_MAX) { | 11296 | switch (dest_ptr_val->data.x_ptr.special) { |
| 11238 | dest_elements = dest_ptr_val->data.x_ptr.base_ptr; | 11297 | case ConstPtrSpecialInvalid: |
| 11239 | start = 0; | 11298 | zig_unreachable(); |
| 11240 | bound_end = 1; | 11299 | case ConstPtrSpecialRef: |
| 11241 | } else { | 11300 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; |
| 11242 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.base_ptr; | 11301 | start = 0; |
| 11243 | dest_elements = array_val->data.x_array.elements; | 11302 | bound_end = 1; |
| 11244 | start = dest_ptr_val->data.x_ptr.index; | 11303 | break; |
| 11245 | bound_end = array_val->data.x_array.size; | 11304 | case ConstPtrSpecialBaseArray: |
| | 11305 | { |
| | 11306 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; |
| | 11307 | dest_elements = array_val->data.x_array.elements; |
| | 11308 | start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; |
| | 11309 | bound_end = array_val->type->data.array.len; |
| | 11310 | break; |
| | 11311 | } |
| | 11312 | case ConstPtrSpecialBaseStruct: |
| | 11313 | zig_panic("TODO memset on const inner struct"); |
| | 11314 | case ConstPtrSpecialHardCodedAddr: |
| | 11315 | zig_unreachable(); |
| 11246 | } | 11316 | } |
| 11247 | | 11317 | |
| 11248 | size_t count = casted_count->value.data.x_bignum.data.x_uint; | 11318 | size_t count = casted_count->value.data.x_bignum.data.x_uint; |
| ... | @@ -11304,7 +11374,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi | ... | @@ -11304,7 +11374,8 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi |
| 11304 | | 11374 | |
| 11305 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && | 11375 | if (casted_dest_ptr->value.special == ConstValSpecialStatic && |
| 11306 | casted_src_ptr->value.special == ConstValSpecialStatic && | 11376 | casted_src_ptr->value.special == ConstValSpecialStatic && |
| 11307 | casted_count->value.special == ConstValSpecialStatic) | 11377 | casted_count->value.special == ConstValSpecialStatic && |
| | 11378 | casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) |
| 11308 | { | 11379 | { |
| 11309 | size_t count = casted_count->value.data.x_bignum.data.x_uint; | 11380 | size_t count = casted_count->value.data.x_bignum.data.x_uint; |
| 11310 | | 11381 | |
| ... | @@ -11312,15 +11383,26 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi | ... | @@ -11312,15 +11383,26 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi |
| 11312 | ConstExprValue *dest_elements; | 11383 | ConstExprValue *dest_elements; |
| 11313 | size_t dest_start; | 11384 | size_t dest_start; |
| 11314 | size_t dest_end; | 11385 | size_t dest_end; |
| 11315 | if (dest_ptr_val->data.x_ptr.index == SIZE_MAX) { | 11386 | switch (dest_ptr_val->data.x_ptr.special) { |
| 11316 | dest_elements = dest_ptr_val->data.x_ptr.base_ptr; | 11387 | case ConstPtrSpecialInvalid: |
| 11317 | dest_start = 0; | 11388 | zig_unreachable(); |
| 11318 | dest_end = 1; | 11389 | case ConstPtrSpecialRef: |
| 11319 | } else { | 11390 | dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; |
| 11320 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.base_ptr; | 11391 | dest_start = 0; |
| 11321 | dest_elements = array_val->data.x_array.elements; | 11392 | dest_end = 1; |
| 11322 | dest_start = dest_ptr_val->data.x_ptr.index; | 11393 | break; |
| 11323 | dest_end = array_val->data.x_array.size; | 11394 | case ConstPtrSpecialBaseArray: |
| | 11395 | { |
| | 11396 | ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; |
| | 11397 | dest_elements = array_val->data.x_array.elements; |
| | 11398 | dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; |
| | 11399 | dest_end = array_val->type->data.array.len; |
| | 11400 | break; |
| | 11401 | } |
| | 11402 | case ConstPtrSpecialBaseStruct: |
| | 11403 | zig_panic("TODO memcpy on const inner struct"); |
| | 11404 | case ConstPtrSpecialHardCodedAddr: |
| | 11405 | zig_unreachable(); |
| 11324 | } | 11406 | } |
| 11325 | | 11407 | |
| 11326 | if (dest_start + count > dest_end) { | 11408 | if (dest_start + count > dest_end) { |
| ... | @@ -11332,15 +11414,27 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi | ... | @@ -11332,15 +11414,27 @@ static TypeTableEntry *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructi |
| 11332 | ConstExprValue *src_elements; | 11414 | ConstExprValue *src_elements; |
| 11333 | size_t src_start; | 11415 | size_t src_start; |
| 11334 | size_t src_end; | 11416 | size_t src_end; |
| 11335 | if (src_ptr_val->data.x_ptr.index == SIZE_MAX) { | 11417 | |
| 11336 | src_elements = src_ptr_val->data.x_ptr.base_ptr; | 11418 | switch (src_ptr_val->data.x_ptr.special) { |
| 11337 | src_start = 0; | 11419 | case ConstPtrSpecialInvalid: |
| 11338 | src_end = 1; | 11420 | zig_unreachable(); |
| 11339 | } else { | 11421 | case ConstPtrSpecialRef: |
| 11340 | ConstExprValue *array_val = src_ptr_val->data.x_ptr.base_ptr; | 11422 | src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; |
| 11341 | src_elements = array_val->data.x_array.elements; | 11423 | src_start = 0; |
| 11342 | src_start = src_ptr_val->data.x_ptr.index; | 11424 | src_end = 1; |
| 11343 | src_end = array_val->data.x_array.size; | 11425 | break; |
| | 11426 | case ConstPtrSpecialBaseArray: |
| | 11427 | { |
| | 11428 | ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; |
| | 11429 | src_elements = array_val->data.x_array.elements; |
| | 11430 | src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; |
| | 11431 | src_end = array_val->type->data.array.len; |
| | 11432 | break; |
| | 11433 | } |
| | 11434 | case ConstPtrSpecialBaseStruct: |
| | 11435 | zig_panic("TODO memcpy on const inner struct"); |
| | 11436 | case ConstPtrSpecialHardCodedAddr: |
| | 11437 | zig_unreachable(); |
| 11344 | } | 11438 | } |
| 11345 | | 11439 | |
| 11346 | if (src_start + count > src_end) { | 11440 | if (src_start + count > src_end) { |
| ... | @@ -11415,68 +11509,115 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -11415,68 +11509,115 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 11415 | casted_start->value.special == ConstValSpecialStatic && | 11509 | casted_start->value.special == ConstValSpecialStatic && |
| 11416 | (!end || end->value.special == ConstValSpecialStatic)) | 11510 | (!end || end->value.special == ConstValSpecialStatic)) |
| 11417 | { | 11511 | { |
| 11418 | ConstExprValue *base_ptr; | 11512 | ConstExprValue *array_val; |
| | 11513 | ConstExprValue *parent_ptr; |
| 11419 | size_t abs_offset; | 11514 | size_t abs_offset; |
| 11420 | size_t rel_end; | 11515 | size_t rel_end; |
| 11421 | if (array_type->id == TypeTableEntryIdArray) { | 11516 | if (array_type->id == TypeTableEntryIdArray) { |
| 11422 | base_ptr = &ptr->value; | 11517 | array_val = &ptr->value; |
| 11423 | abs_offset = 0; | 11518 | abs_offset = 0; |
| 11424 | rel_end = array_type->data.array.len; | 11519 | rel_end = array_type->data.array.len; |
| | 11520 | parent_ptr = nullptr; |
| 11425 | } else if (array_type->id == TypeTableEntryIdPointer) { | 11521 | } else if (array_type->id == TypeTableEntryIdPointer) { |
| 11426 | base_ptr = ptr->value.data.x_ptr.base_ptr; | 11522 | parent_ptr = &ptr->value; |
| 11427 | abs_offset = ptr->value.data.x_ptr.index; | 11523 | switch (parent_ptr->data.x_ptr.special) { |
| 11428 | if (abs_offset == SIZE_MAX) { | 11524 | case ConstPtrSpecialInvalid: |
| 11429 | rel_end = 1; | 11525 | zig_unreachable(); |
| 11430 | } else { | 11526 | case ConstPtrSpecialRef: |
| 11431 | rel_end = base_ptr->data.x_array.size - abs_offset; | 11527 | array_val = nullptr; |
| | 11528 | abs_offset = SIZE_MAX; |
| | 11529 | rel_end = 1; |
| | 11530 | break; |
| | 11531 | case ConstPtrSpecialBaseArray: |
| | 11532 | array_val = parent_ptr->data.x_ptr.data.base_array.array_val; |
| | 11533 | abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; |
| | 11534 | rel_end = array_val->type->data.array.len - abs_offset; |
| | 11535 | break; |
| | 11536 | case ConstPtrSpecialBaseStruct: |
| | 11537 | zig_panic("TODO slice const inner struct"); |
| | 11538 | case ConstPtrSpecialHardCodedAddr: |
| | 11539 | array_val = nullptr; |
| | 11540 | break; |
| 11432 | } | 11541 | } |
| 11433 | } else if (is_slice(array_type)) { | 11542 | } else if (is_slice(array_type)) { |
| 11434 | ConstExprValue *ptr_val = &ptr->value.data.x_struct.fields[slice_ptr_index]; | 11543 | parent_ptr = &ptr->value.data.x_struct.fields[slice_ptr_index]; |
| 11435 | ConstExprValue *len_val = &ptr->value.data.x_struct.fields[slice_len_index]; | 11544 | ConstExprValue *len_val = &ptr->value.data.x_struct.fields[slice_len_index]; |
| 11436 | base_ptr = ptr_val->data.x_ptr.base_ptr; | | |
| 11437 | abs_offset = ptr_val->data.x_ptr.index; | | |
| 11438 | | 11545 | |
| 11439 | if (ptr_val->data.x_ptr.index == SIZE_MAX) { | 11546 | switch (parent_ptr->data.x_ptr.special) { |
| 11440 | rel_end = 1; | 11547 | case ConstPtrSpecialInvalid: |
| 11441 | } else { | 11548 | zig_unreachable(); |
| 11442 | rel_end = len_val->data.x_bignum.data.x_uint; | 11549 | case ConstPtrSpecialRef: |
| | 11550 | array_val = nullptr; |
| | 11551 | abs_offset = SIZE_MAX; |
| | 11552 | rel_end = 1; |
| | 11553 | break; |
| | 11554 | case ConstPtrSpecialBaseArray: |
| | 11555 | array_val = parent_ptr->data.x_ptr.data.base_array.array_val; |
| | 11556 | abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; |
| | 11557 | rel_end = len_val->data.x_bignum.data.x_uint; |
| | 11558 | break; |
| | 11559 | case ConstPtrSpecialBaseStruct: |
| | 11560 | zig_panic("TODO slice const inner struct"); |
| | 11561 | case ConstPtrSpecialHardCodedAddr: |
| | 11562 | array_val = nullptr; |
| | 11563 | break; |
| 11443 | } | 11564 | } |
| 11444 | } else { | 11565 | } else { |
| 11445 | zig_unreachable(); | 11566 | zig_unreachable(); |
| 11446 | } | 11567 | } |
| 11447 | | 11568 | |
| 11448 | uint64_t start_scalar = casted_start->value.data.x_bignum.data.x_uint; | 11569 | if (array_val || parent_ptr->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { |
| 11449 | if (start_scalar > rel_end) { | 11570 | uint64_t start_scalar = casted_start->value.data.x_bignum.data.x_uint; |
| 11450 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); | 11571 | if (start_scalar > rel_end) { |
| 11451 | return ira->codegen->builtin_types.entry_invalid; | 11572 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); |
| 11452 | } | 11573 | return ira->codegen->builtin_types.entry_invalid; |
| | 11574 | } |
| 11453 | | 11575 | |
| 11454 | uint64_t end_scalar; | 11576 | uint64_t end_scalar; |
| 11455 | if (end) { | 11577 | if (end) { |
| 11456 | end_scalar = end->value.data.x_bignum.data.x_uint; | 11578 | end_scalar = end->value.data.x_bignum.data.x_uint; |
| 11457 | } else { | 11579 | } else { |
| 11458 | end_scalar = rel_end; | 11580 | end_scalar = rel_end; |
| 11459 | } | 11581 | } |
| 11460 | if (end_scalar > rel_end) { | 11582 | if (end_scalar > rel_end) { |
| 11461 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); | 11583 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); |
| 11462 | return ira->codegen->builtin_types.entry_invalid; | 11584 | return ira->codegen->builtin_types.entry_invalid; |
| 11463 | } | 11585 | } |
| 11464 | if (start_scalar > end_scalar) { | 11586 | if (start_scalar > end_scalar) { |
| 11465 | ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); | 11587 | ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); |
| 11466 | return ira->codegen->builtin_types.entry_invalid; | 11588 | return ira->codegen->builtin_types.entry_invalid; |
| 11467 | } | 11589 | } |
| 11468 | | 11590 | |
| 11469 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 11591 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 11470 | out_val->data.x_struct.fields = allocate<ConstExprValue>(2); | 11592 | out_val->data.x_struct.fields = allocate<ConstExprValue>(2); |
| 11471 | | 11593 | |
| 11472 | ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; | 11594 | ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; |
| 11473 | size_t index = (abs_offset != SIZE_MAX) ? (abs_offset + start_scalar) : SIZE_MAX; | 11595 | |
| 11474 | init_const_ptr(ira->codegen, ptr_val, base_ptr, index, instruction->is_const); | 11596 | if (array_val) { |
| | 11597 | size_t index = abs_offset + start_scalar; |
| | 11598 | init_const_ptr_array(ira->codegen, ptr_val, array_val, index, instruction->is_const); |
| | 11599 | } else { |
| | 11600 | switch (parent_ptr->data.x_ptr.special) { |
| | 11601 | case ConstPtrSpecialInvalid: |
| | 11602 | zig_unreachable(); |
| | 11603 | case ConstPtrSpecialRef: |
| | 11604 | init_const_ptr_ref(ira->codegen, ptr_val, |
| | 11605 | parent_ptr->data.x_ptr.data.ref.pointee, instruction->is_const); |
| | 11606 | break; |
| | 11607 | case ConstPtrSpecialBaseArray: |
| | 11608 | zig_unreachable(); |
| | 11609 | case ConstPtrSpecialBaseStruct: |
| | 11610 | zig_panic("TODO"); |
| | 11611 | case ConstPtrSpecialHardCodedAddr: |
| | 11612 | zig_unreachable(); |
| | 11613 | } |
| | 11614 | } |
| 11475 | | 11615 | |
| 11476 | ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; | 11616 | ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; |
| 11477 | init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); | 11617 | init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); |
| 11478 | | 11618 | |
| 11479 | return return_type; | 11619 | return return_type; |
| | 11620 | } |
| 11480 | } | 11621 | } |
| 11481 | | 11622 | |
| 11482 | IrInstruction *new_instruction = ir_build_slice_from(&ira->new_irb, &instruction->base, ptr, | 11623 | IrInstruction *new_instruction = ir_build_slice_from(&ira->new_irb, &instruction->base, ptr, |
| ... | @@ -11688,8 +11829,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, | ... | @@ -11688,8 +11829,7 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, |
| 11688 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); | 11829 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); |
| 11689 | if (!ptr_val) | 11830 | if (!ptr_val) |
| 11690 | return ira->codegen->builtin_types.entry_invalid; | 11831 | return ira->codegen->builtin_types.entry_invalid; |
| 11691 | ConstExprValue *err_union_val = ptr_val->data.x_ptr.base_ptr; | 11832 | ConstExprValue *err_union_val = const_ptr_pointee(ptr_val); |
| 11692 | assert(ptr_val->data.x_ptr.index == SIZE_MAX); | | |
| 11693 | if (err_union_val->special != ConstValSpecialRuntime) { | 11833 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 11694 | ErrorTableEntry *err = err_union_val->data.x_err_union.err; | 11834 | ErrorTableEntry *err = err_union_val->data.x_err_union.err; |
| 11695 | assert(err); | 11835 | assert(err); |
| ... | @@ -11728,13 +11868,13 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -11728,13 +11868,13 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 11728 | return ira->codegen->builtin_types.entry_invalid; | 11868 | return ira->codegen->builtin_types.entry_invalid; |
| 11729 | } else if (canon_type->id == TypeTableEntryIdErrorUnion) { | 11869 | } else if (canon_type->id == TypeTableEntryIdErrorUnion) { |
| 11730 | TypeTableEntry *child_type = canon_type->data.error.child_type; | 11870 | TypeTableEntry *child_type = canon_type->data.error.child_type; |
| 11731 | TypeTableEntry *result_type = get_pointer_to_type(ira->codegen, child_type, false); | 11871 | TypeTableEntry *result_type = get_pointer_to_type_volatile(ira->codegen, child_type, |
| | 11872 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile); |
| 11732 | if (instr_is_comptime(value)) { | 11873 | if (instr_is_comptime(value)) { |
| 11733 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); | 11874 | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); |
| 11734 | if (!ptr_val) | 11875 | if (!ptr_val) |
| 11735 | return ira->codegen->builtin_types.entry_invalid; | 11876 | return ira->codegen->builtin_types.entry_invalid; |
| 11736 | ConstExprValue *err_union_val = ptr_val->data.x_ptr.base_ptr; | 11877 | ConstExprValue *err_union_val = const_ptr_pointee(ptr_val); |
| 11737 | assert(ptr_val->data.x_ptr.index == SIZE_MAX); | | |
| 11738 | if (err_union_val->special != ConstValSpecialRuntime) { | 11878 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 11739 | ErrorTableEntry *err = err_union_val->data.x_err_union.err; | 11879 | ErrorTableEntry *err = err_union_val->data.x_err_union.err; |
| 11740 | if (err != nullptr) { | 11880 | if (err != nullptr) { |
| ... | @@ -11744,8 +11884,8 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, | ... | @@ -11744,8 +11884,8 @@ static TypeTableEntry *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, |
| 11744 | } | 11884 | } |
| 11745 | | 11885 | |
| 11746 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 11886 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 11747 | out_val->data.x_ptr.base_ptr = err_union_val->data.x_err_union.payload; | 11887 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 11748 | out_val->data.x_ptr.index = SIZE_MAX; | 11888 | out_val->data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; |
| 11749 | return result_type; | 11889 | return result_type; |
| 11750 | } | 11890 | } |
| 11751 | } | 11891 | } |