| ... | @@ -12538,6 +12538,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -12538,6 +12538,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 12538 | const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); | 12538 | const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs); |
| 12539 | const operand = sema.resolveInst(extra.rhs); | 12539 | const operand = sema.resolveInst(extra.rhs); |
| 12540 | const operand_ty = sema.typeOf(operand); | 12540 | const operand_ty = sema.typeOf(operand); |
| | 12541 | const target = sema.mod.getTarget(); |
| | 12542 | |
| 12541 | try sema.checkPtrType(block, dest_ty_src, dest_ty); | 12543 | try sema.checkPtrType(block, dest_ty_src, dest_ty); |
| 12542 | try sema.checkPtrOperand(block, operand_src, operand_ty); | 12544 | try sema.checkPtrOperand(block, operand_src, operand_ty); |
| 12543 | if (dest_ty.isSlice()) { | 12545 | if (dest_ty.isSlice()) { |
| ... | @@ -12547,7 +12549,28 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -12547,7 +12549,28 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 12547 | try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty) | 12549 | try sema.analyzeSlicePtr(block, operand_src, operand, operand_ty) |
| 12548 | else | 12550 | else |
| 12549 | operand; | 12551 | operand; |
| 12550 | return sema.coerceCompatiblePtrs(block, dest_ty, ptr, operand_src); | 12552 | |
| | 12553 | try sema.resolveTypeLayout(block, dest_ty_src, dest_ty.elemType2()); |
| | 12554 | const dest_align = dest_ty.ptrAlignment(target); |
| | 12555 | try sema.resolveTypeLayout(block, operand_src, operand_ty.elemType2()); |
| | 12556 | const operand_align = operand_ty.ptrAlignment(target); |
| | 12557 | |
| | 12558 | // If the destination is less aligned than the source, preserve the source alignment |
| | 12559 | var aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: { |
| | 12560 | // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result |
| | 12561 | if (dest_ty.zigTypeTag() == .Optional) { |
| | 12562 | var buf: Type.Payload.ElemType = undefined; |
| | 12563 | var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data; |
| | 12564 | dest_ptr_info.@"align" = operand_align; |
| | 12565 | break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, target, dest_ptr_info)); |
| | 12566 | } else { |
| | 12567 | var dest_ptr_info = dest_ty.ptrInfo().data; |
| | 12568 | dest_ptr_info.@"align" = operand_align; |
| | 12569 | break :blk try Type.ptr(sema.arena, target, dest_ptr_info); |
| | 12570 | } |
| | 12571 | }; |
| | 12572 | |
| | 12573 | return sema.coerceCompatiblePtrs(block, aligned_dest_ty, ptr, operand_src); |
| 12551 | } | 12574 | } |
| 12552 | | 12575 | |
| 12553 | fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 12576 | fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| ... | @@ -15340,7 +15363,7 @@ fn unionFieldVal( | ... | @@ -15340,7 +15363,7 @@ fn unionFieldVal( |
| 15340 | return sema.addConstant(field.ty, tag_and_val.val); | 15363 | return sema.addConstant(field.ty, tag_and_val.val); |
| 15341 | } else { | 15364 | } else { |
| 15342 | const old_ty = union_ty.unionFieldType(tag_and_val.tag); | 15365 | const old_ty = union_ty.unionFieldType(tag_and_val.tag); |
| 15343 | const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty); | 15366 | const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty, 0); |
| 15344 | return sema.addConstant(field.ty, new_val); | 15367 | return sema.addConstant(field.ty, new_val); |
| 15345 | } | 15368 | } |
| 15346 | }, | 15369 | }, |
| ... | @@ -16447,7 +16470,7 @@ fn storePtrVal( | ... | @@ -16447,7 +16470,7 @@ fn storePtrVal( |
| 16447 | var kit = try beginComptimePtrMutation(sema, block, src, ptr_val); | 16470 | var kit = try beginComptimePtrMutation(sema, block, src, ptr_val); |
| 16448 | try sema.checkComptimeVarStore(block, src, kit.decl_ref_mut); | 16471 | try sema.checkComptimeVarStore(block, src, kit.decl_ref_mut); |
| 16449 | | 16472 | |
| 16450 | const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, kit.ty); | 16473 | const bitcasted_val = try sema.bitCastVal(block, src, operand_val, operand_ty, kit.ty, 0); |
| 16451 | | 16474 | |
| 16452 | const arena = kit.beginArena(sema.gpa); | 16475 | const arena = kit.beginArena(sema.gpa); |
| 16453 | defer kit.finishArena(); | 16476 | defer kit.finishArena(); |
| ... | @@ -16741,6 +16764,8 @@ fn beginComptimePtrMutation( | ... | @@ -16741,6 +16764,8 @@ fn beginComptimePtrMutation( |
| 16741 | const ComptimePtrLoadKit = struct { | 16764 | const ComptimePtrLoadKit = struct { |
| 16742 | /// The Value of the Decl that owns this memory. | 16765 | /// The Value of the Decl that owns this memory. |
| 16743 | root_val: Value, | 16766 | root_val: Value, |
| | 16767 | /// The Type of the Decl that owns this memory. |
| | 16768 | root_ty: Type, |
| 16744 | /// Parent Value. | 16769 | /// Parent Value. |
| 16745 | val: Value, | 16770 | val: Value, |
| 16746 | /// The Type of the parent Value. | 16771 | /// The Type of the parent Value. |
| ... | @@ -16771,6 +16796,7 @@ fn beginComptimePtrLoad( | ... | @@ -16771,6 +16796,7 @@ fn beginComptimePtrLoad( |
| 16771 | if (decl_val.tag() == .variable) return error.RuntimeLoad; | 16796 | if (decl_val.tag() == .variable) return error.RuntimeLoad; |
| 16772 | return ComptimePtrLoadKit{ | 16797 | return ComptimePtrLoadKit{ |
| 16773 | .root_val = decl_val, | 16798 | .root_val = decl_val, |
| | 16799 | .root_ty = decl.ty, |
| 16774 | .val = decl_val, | 16800 | .val = decl_val, |
| 16775 | .ty = decl.ty, | 16801 | .ty = decl.ty, |
| 16776 | .byte_offset = 0, | 16802 | .byte_offset = 0, |
| ... | @@ -16783,6 +16809,7 @@ fn beginComptimePtrLoad( | ... | @@ -16783,6 +16809,7 @@ fn beginComptimePtrLoad( |
| 16783 | if (decl_val.tag() == .variable) return error.RuntimeLoad; | 16809 | if (decl_val.tag() == .variable) return error.RuntimeLoad; |
| 16784 | return ComptimePtrLoadKit{ | 16810 | return ComptimePtrLoadKit{ |
| 16785 | .root_val = decl_val, | 16811 | .root_val = decl_val, |
| | 16812 | .root_ty = decl.ty, |
| 16786 | .val = decl_val, | 16813 | .val = decl_val, |
| 16787 | .ty = decl.ty, | 16814 | .ty = decl.ty, |
| 16788 | .byte_offset = 0, | 16815 | .byte_offset = 0, |
| ... | @@ -16817,6 +16844,7 @@ fn beginComptimePtrLoad( | ... | @@ -16817,6 +16844,7 @@ fn beginComptimePtrLoad( |
| 16817 | }; | 16844 | }; |
| 16818 | return ComptimePtrLoadKit{ | 16845 | return ComptimePtrLoadKit{ |
| 16819 | .root_val = parent.root_val, | 16846 | .root_val = parent.root_val, |
| | 16847 | .root_ty = parent.ty, |
| 16820 | .val = try parent.val.elemValue(sema.arena, elem_ptr.index), | 16848 | .val = try parent.val.elemValue(sema.arena, elem_ptr.index), |
| 16821 | .ty = elem_ty, | 16849 | .ty = elem_ty, |
| 16822 | .byte_offset = byte_offset, | 16850 | .byte_offset = byte_offset, |
| ... | @@ -16832,6 +16860,7 @@ fn beginComptimePtrLoad( | ... | @@ -16832,6 +16860,7 @@ fn beginComptimePtrLoad( |
| 16832 | } | 16860 | } |
| 16833 | return ComptimePtrLoadKit{ | 16861 | return ComptimePtrLoadKit{ |
| 16834 | .root_val = parent.root_val, | 16862 | .root_val = parent.root_val, |
| | 16863 | .root_ty = parent.ty, |
| 16835 | .val = parent.val, | 16864 | .val = parent.val, |
| 16836 | .ty = parent.ty, | 16865 | .ty = parent.ty, |
| 16837 | .byte_offset = parent.byte_offset, | 16866 | .byte_offset = parent.byte_offset, |
| ... | @@ -16859,6 +16888,7 @@ fn beginComptimePtrLoad( | ... | @@ -16859,6 +16888,7 @@ fn beginComptimePtrLoad( |
| 16859 | }; | 16888 | }; |
| 16860 | return ComptimePtrLoadKit{ | 16889 | return ComptimePtrLoadKit{ |
| 16861 | .root_val = parent.root_val, | 16890 | .root_val = parent.root_val, |
| | 16891 | .root_ty = parent.ty, |
| 16862 | .val = try parent.val.fieldValue(sema.arena, field_index), | 16892 | .val = try parent.val.fieldValue(sema.arena, field_index), |
| 16863 | .ty = parent.ty.structFieldType(field_index), | 16893 | .ty = parent.ty.structFieldType(field_index), |
| 16864 | .byte_offset = byte_offset, | 16894 | .byte_offset = byte_offset, |
| ... | @@ -16870,6 +16900,7 @@ fn beginComptimePtrLoad( | ... | @@ -16870,6 +16900,7 @@ fn beginComptimePtrLoad( |
| 16870 | const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr); | 16900 | const parent = try beginComptimePtrLoad(sema, block, src, err_union_ptr); |
| 16871 | return ComptimePtrLoadKit{ | 16901 | return ComptimePtrLoadKit{ |
| 16872 | .root_val = parent.root_val, | 16902 | .root_val = parent.root_val, |
| | 16903 | .root_ty = parent.root_ty, |
| 16873 | .val = parent.val.castTag(.eu_payload).?.data, | 16904 | .val = parent.val.castTag(.eu_payload).?.data, |
| 16874 | .ty = parent.ty.errorUnionPayload(), | 16905 | .ty = parent.ty.errorUnionPayload(), |
| 16875 | .byte_offset = null, | 16906 | .byte_offset = null, |
| ... | @@ -16881,6 +16912,7 @@ fn beginComptimePtrLoad( | ... | @@ -16881,6 +16912,7 @@ fn beginComptimePtrLoad( |
| 16881 | const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr); | 16912 | const parent = try beginComptimePtrLoad(sema, block, src, opt_ptr); |
| 16882 | return ComptimePtrLoadKit{ | 16913 | return ComptimePtrLoadKit{ |
| 16883 | .root_val = parent.root_val, | 16914 | .root_val = parent.root_val, |
| | 16915 | .root_ty = parent.root_ty, |
| 16884 | .val = parent.val.castTag(.opt_payload).?.data, | 16916 | .val = parent.val.castTag(.opt_payload).?.data, |
| 16885 | .ty = try parent.ty.optionalChildAlloc(sema.arena), | 16917 | .ty = try parent.ty.optionalChildAlloc(sema.arena), |
| 16886 | .byte_offset = null, | 16918 | .byte_offset = null, |
| ... | @@ -16918,7 +16950,7 @@ fn bitCast( | ... | @@ -16918,7 +16950,7 @@ fn bitCast( |
| 16918 | | 16950 | |
| 16919 | // TODO validate the type size and other compile errors | 16951 | // TODO validate the type size and other compile errors |
| 16920 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { | 16952 | if (try sema.resolveMaybeUndefVal(block, inst_src, inst)) |val| { |
| 16921 | const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty); | 16953 | const result_val = try sema.bitCastVal(block, inst_src, val, old_ty, dest_ty, 0); |
| 16922 | return sema.addConstant(dest_ty, result_val); | 16954 | return sema.addConstant(dest_ty, result_val); |
| 16923 | } | 16955 | } |
| 16924 | try sema.requireRuntimeBlock(block, inst_src); | 16956 | try sema.requireRuntimeBlock(block, inst_src); |
| ... | @@ -16932,6 +16964,7 @@ pub fn bitCastVal( | ... | @@ -16932,6 +16964,7 @@ pub fn bitCastVal( |
| 16932 | val: Value, | 16964 | val: Value, |
| 16933 | old_ty: Type, | 16965 | old_ty: Type, |
| 16934 | new_ty: Type, | 16966 | new_ty: Type, |
| | 16967 | buffer_offset: usize, |
| 16935 | ) !Value { | 16968 | ) !Value { |
| 16936 | if (old_ty.eql(new_ty)) return val; | 16969 | if (old_ty.eql(new_ty)) return val; |
| 16937 | | 16970 | |
| ... | @@ -16942,7 +16975,7 @@ pub fn bitCastVal( | ... | @@ -16942,7 +16975,7 @@ pub fn bitCastVal( |
| 16942 | const buffer = try sema.gpa.alloc(u8, abi_size); | 16975 | const buffer = try sema.gpa.alloc(u8, abi_size); |
| 16943 | defer sema.gpa.free(buffer); | 16976 | defer sema.gpa.free(buffer); |
| 16944 | val.writeToMemory(old_ty, target, buffer); | 16977 | val.writeToMemory(old_ty, target, buffer); |
| 16945 | return Value.readFromMemory(new_ty, target, buffer, sema.arena); | 16978 | return Value.readFromMemory(new_ty, target, buffer[buffer_offset..], sema.arena); |
| 16946 | } | 16979 | } |
| 16947 | | 16980 | |
| 16948 | fn coerceArrayPtrToSlice( | 16981 | fn coerceArrayPtrToSlice( |
| ... | @@ -19808,13 +19841,10 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr | ... | @@ -19808,13 +19841,10 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr |
| 19808 | // The Type it is stored as in the compiler has an ABI size greater or equal to | 19841 | // The Type it is stored as in the compiler has an ABI size greater or equal to |
| 19809 | // the ABI size of `load_ty`. We may perform the bitcast based on | 19842 | // the ABI size of `load_ty`. We may perform the bitcast based on |
| 19810 | // `parent.val` alone (more efficient). | 19843 | // `parent.val` alone (more efficient). |
| 19811 | return try sema.bitCastVal(block, src, parent.val, parent.ty, load_ty); | 19844 | return try sema.bitCastVal(block, src, parent.val, parent.ty, load_ty, 0); |
| | 19845 | } else { |
| | 19846 | return try sema.bitCastVal(block, src, parent.root_val, parent.root_ty, load_ty, parent.byte_offset.?); |
| 19812 | } | 19847 | } |
| 19813 | | | |
| 19814 | // The Type it is stored as in the compiler has an ABI size less than the ABI size | | |
| 19815 | // of `load_ty`. The bitcast must be performed based on the `parent.root_val` | | |
| 19816 | // and reinterpreted starting at `parent.byte_offset`. | | |
| 19817 | return sema.fail(block, src, "TODO: implement bitcast with index offset", .{}); | | |
| 19818 | } | 19848 | } |
| 19819 | | 19849 | |
| 19820 | /// Used to convert a u64 value to a usize value, emitting a compile error if the number | 19850 | /// Used to convert a u64 value to a usize value, emitting a compile error if the number |