@@ -107,6 +107,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
107107static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, VariableTableEntry *var);
108108static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);
109109static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
110+ static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, uint32_t new_align);
110111
111112ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
112113 assert(const_val->type->id == TypeTableEntryIdPointer);
@@ -6849,7 +6850,11 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
68496850 IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr);
68506851 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0);
68516852 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle);
6852- IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type, coro_mem_ptr_maybe);
6853+ IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node,
6854+ get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8,
6855+ false, false, PtrLenUnknown, get_abi_alignment(irb->codegen, irb->codegen->builtin_types.entry_u8),
6856+ 0, 0));
6857+ IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, coro_mem_ptr_maybe);
68536858 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false);
68546859 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var);
68556860 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr);
@@ -8729,6 +8734,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
87298734 case CastOpNoCast:
87308735 zig_unreachable();
87318736 case CastOpErrSet:
8737+ case CastOpBitCast:
87328738 zig_panic("TODO");
87338739 case CastOpNoop:
87348740 {
@@ -9750,6 +9756,49 @@ static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *sourc
97509756 return result;
97519757}
97529758
9759+ static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
9760+ TypeTableEntry *wanted_type)
9761+ {
9762+ assert(wanted_type->id == TypeTableEntryIdPointer);
9763+ wanted_type = adjust_ptr_align(ira->codegen, wanted_type, target->value.type->data.pointer.alignment);
9764+ TypeTableEntry *array_type = wanted_type->data.pointer.child_type;
9765+ assert(array_type->id == TypeTableEntryIdArray);
9766+ assert(array_type->data.array.len == 1);
9767+
9768+ if (instr_is_comptime(target)) {
9769+ ConstExprValue *val = ir_resolve_const(ira, target, UndefBad);
9770+ if (!val)
9771+ return ira->codegen->invalid_instruction;
9772+
9773+ assert(val->type->id == TypeTableEntryIdPointer);
9774+ ConstExprValue *pointee = const_ptr_pointee(ira->codegen, val);
9775+ if (pointee->special != ConstValSpecialRuntime) {
9776+ ConstExprValue *array_val = create_const_vals(1);
9777+ array_val->special = ConstValSpecialStatic;
9778+ array_val->type = array_type;
9779+ array_val->data.x_array.special = ConstArraySpecialNone;
9780+ array_val->data.x_array.s_none.elements = pointee;
9781+ array_val->data.x_array.s_none.parent.id = ConstParentIdScalar;
9782+ array_val->data.x_array.s_none.parent.data.p_scalar.scalar_val = pointee;
9783+
9784+ IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb,
9785+ source_instr->scope, source_instr->source_node);
9786+ const_instruction->base.value.type = wanted_type;
9787+ const_instruction->base.value.special = ConstValSpecialStatic;
9788+ const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialRef;
9789+ const_instruction->base.value.data.x_ptr.data.ref.pointee = array_val;
9790+ const_instruction->base.value.data.x_ptr.mut = val->data.x_ptr.mut;
9791+ return &const_instruction->base;
9792+ }
9793+ }
9794+
9795+ // pointer to array and pointer to single item are represented the same way at runtime
9796+ IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node,
9797+ wanted_type, target, CastOpBitCast);
9798+ result->value.type = wanted_type;
9799+ return result;
9800+ }
9801+
97539802static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr,
97549803 TypeTableEntry *wanted_type, IrInstruction *value)
97559804{
@@ -10156,6 +10205,30 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1015610205 }
1015710206 }
1015810207
10208+ // explicit cast from *T to *[1]T
10209+ if (wanted_type->id == TypeTableEntryIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle &&
10210+ actual_type->id == TypeTableEntryIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle)
10211+ {
10212+ TypeTableEntry *array_type = wanted_type->data.pointer.child_type;
10213+ if (array_type->id == TypeTableEntryIdArray && array_type->data.array.len == 1 &&
10214+ types_match_const_cast_only(ira, array_type->data.array.child_type,
10215+ actual_type->data.pointer.child_type, source_node).id == ConstCastResultIdOk)
10216+ {
10217+ if (wanted_type->data.pointer.alignment > actual_type->data.pointer.alignment) {
10218+ ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment"));
10219+ add_error_note(ira->codegen, msg, value->source_node,
10220+ buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&actual_type->name),
10221+ actual_type->data.pointer.alignment));
10222+ add_error_note(ira->codegen, msg, source_instr->source_node,
10223+ buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&wanted_type->name),
10224+ wanted_type->data.pointer.alignment));
10225+ return ira->codegen->invalid_instruction;
10226+ }
10227+ return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type);
10228+ }
10229+ }
10230+
10231+
1015910232 // explicit cast from undefined to anything
1016010233 if (actual_type->id == TypeTableEntryIdUndefLit) {
1016110234 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type);
@@ -13162,11 +13235,13 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1316213235 if (type_is_invalid(array_ptr->value.type))
1316313236 return ira->codegen->builtin_types.entry_invalid;
1316413237
13238+ ConstExprValue *orig_array_ptr_val = &array_ptr->value;
13239+
1316513240 IrInstruction *elem_index = elem_ptr_instruction->elem_index->other;
1316613241 if (type_is_invalid(elem_index->value.type))
1316713242 return ira->codegen->builtin_types.entry_invalid;
1316813243
13169- TypeTableEntry *ptr_type = array_ptr->value. type;
13244+ TypeTableEntry *ptr_type = orig_array_ptr_val-> type;
1317013245 assert(ptr_type->id == TypeTableEntryIdPointer);
1317113246
1317213247 TypeTableEntry *array_type = ptr_type->data.pointer.child_type;
@@ -13177,7 +13252,18 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1317713252
1317813253 if (type_is_invalid(array_type)) {
1317913254 return array_type;
13180- } else if (array_type->id == TypeTableEntryIdArray) {
13255+ } else if (array_type->id == TypeTableEntryIdArray ||
13256+ (array_type->id == TypeTableEntryIdPointer &&
13257+ array_type->data.pointer.ptr_len == PtrLenSingle &&
13258+ array_type->data.pointer.child_type->id == TypeTableEntryIdArray))
13259+ {
13260+ if (array_type->id == TypeTableEntryIdPointer) {
13261+ array_type = array_type->data.pointer.child_type;
13262+ ptr_type = ptr_type->data.pointer.child_type;
13263+ if (orig_array_ptr_val->special != ConstValSpecialRuntime) {
13264+ orig_array_ptr_val = const_ptr_pointee(ira->codegen, orig_array_ptr_val);
13265+ }
13266+ }
1318113267 if (array_type->data.array.len == 0) {
1318213268 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
1318313269 buf_sprintf("index 0 outside array of size 0"));
@@ -13205,7 +13291,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1320513291 } else if (array_type->id == TypeTableEntryIdPointer) {
1320613292 if (array_type->data.pointer.ptr_len == PtrLenSingle) {
1320713293 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
13208- buf_sprintf("indexing not allowed on pointer to single item"));
13294+ buf_sprintf("index of single- item pointer "));
1320913295 return ira->codegen->builtin_types.entry_invalid;
1321013296 }
1321113297 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len);
@@ -13294,9 +13380,9 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1329413380 }
1329513381
1329613382 ConstExprValue *array_ptr_val;
13297- if (array_ptr->value. special != ConstValSpecialRuntime &&
13298- (array_ptr->value. data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) &&
13299- (array_ptr_val = const_ptr_pointee(ira->codegen, &array_ptr->value )) &&
13383+ if (orig_array_ptr_val-> special != ConstValSpecialRuntime &&
13384+ (orig_array_ptr_val-> data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == TypeTableEntryIdArray) &&
13385+ (array_ptr_val = const_ptr_pointee(ira->codegen, orig_array_ptr_val )) &&
1330013386 array_ptr_val->special != ConstValSpecialRuntime &&
1330113387 (array_type->id != TypeTableEntryIdPointer ||
1330213388 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr))
@@ -13401,7 +13487,7 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
1340113487 } else if (array_type->id == TypeTableEntryIdArray) {
1340213488 ConstExprValue *out_val = ir_build_const_from(ira, &elem_ptr_instruction->base);
1340313489 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray;
13404- out_val->data.x_ptr.mut = array_ptr->value. data.x_ptr.mut;
13490+ out_val->data.x_ptr.mut = orig_array_ptr_val-> data.x_ptr.mut;
1340513491 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val;
1340613492 out_val->data.x_ptr.data.base_array.elem_index = index;
1340713493 return return_type;
@@ -17406,14 +17492,29 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1740617492 byte_alignment, 0, 0);
1740717493 return_type = get_slice_type(ira->codegen, slice_ptr_type);
1740817494 } else if (array_type->id == TypeTableEntryIdPointer) {
17409- TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,
17410- array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
17411- PtrLenUnknown,
17412- array_type->data.pointer.alignment, 0, 0);
17413- return_type = get_slice_type(ira->codegen, slice_ptr_type);
17414- if (!end) {
17415- ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value"));
17416- return ira->codegen->builtin_types.entry_invalid;
17495+ if (array_type->data.pointer.ptr_len == PtrLenSingle) {
17496+ TypeTableEntry *main_type = array_type->data.pointer.child_type;
17497+ if (main_type->id == TypeTableEntryIdArray) {
17498+ TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen,
17499+ main_type->data.pointer.child_type,
17500+ array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
17501+ PtrLenUnknown,
17502+ array_type->data.pointer.alignment, 0, 0);
17503+ return_type = get_slice_type(ira->codegen, slice_ptr_type);
17504+ } else {
17505+ ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer"));
17506+ return ira->codegen->builtin_types.entry_invalid;
17507+ }
17508+ } else {
17509+ TypeTableEntry *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.pointer.child_type,
17510+ array_type->data.pointer.is_const, array_type->data.pointer.is_volatile,
17511+ PtrLenUnknown,
17512+ array_type->data.pointer.alignment, 0, 0);
17513+ return_type = get_slice_type(ira->codegen, slice_ptr_type);
17514+ if (!end) {
17515+ ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value"));
17516+ return ira->codegen->builtin_types.entry_invalid;
17517+ }
1741717518 }
1741817519 } else if (is_slice(array_type)) {
1741917520 TypeTableEntry *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry;
@@ -17433,12 +17534,24 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1743317534 size_t abs_offset;
1743417535 size_t rel_end;
1743517536 bool ptr_is_undef = false;
17436- if (array_type->id == TypeTableEntryIdArray) {
17437- array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
17438- abs_offset = 0;
17439- rel_end = array_type->data.array.len;
17440- parent_ptr = nullptr;
17537+ if (array_type->id == TypeTableEntryIdArray ||
17538+ (array_type->id == TypeTableEntryIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle))
17539+ {
17540+ if (array_type->id == TypeTableEntryIdPointer) {
17541+ TypeTableEntry *child_array_type = array_type->data.pointer.child_type;
17542+ assert(child_array_type->id == TypeTableEntryIdArray);
17543+ parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
17544+ array_val = const_ptr_pointee(ira->codegen, parent_ptr);
17545+ rel_end = child_array_type->data.array.len;
17546+ abs_offset = 0;
17547+ } else {
17548+ array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
17549+ rel_end = array_type->data.array.len;
17550+ parent_ptr = nullptr;
17551+ abs_offset = 0;
17552+ }
1744117553 } else if (array_type->id == TypeTableEntryIdPointer) {
17554+ assert(array_type->data.pointer.ptr_len == PtrLenUnknown);
1744217555 parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value);
1744317556 if (parent_ptr->special == ConstValSpecialUndef) {
1744417557 array_val = nullptr;
@@ -17537,7 +17650,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio
1753717650 if (array_val) {
1753817651 size_t index = abs_offset + start_scalar;
1753917652 bool is_const = slice_is_const(return_type);
17540- init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const);
17653+ init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const, PtrLenUnknown );
1754117654 if (array_type->id == TypeTableEntryIdArray) {
1754217655 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut;
1754317656 } else if (is_slice(array_type)) {
0 commit comments