| author | |
| committer | |
| log | 9ec0017f460854300004ab263bf585c2d376d1fb |
| tree | df586141cc238241a5ce4d9898a119c217baf78c |
| parent | 70a4b76acaef8d4062f4d5317af398929ea6c9c4 |
11 files changed, 152 insertions(+), 85 deletions(-)
src/Air.zig+9-5| ... | ... | @@ -1427,8 +1427,11 @@ pub fn getRefType(air: Air, ref: Air.Inst.Ref) Type { |
| 1427 | 1427 | const inst_index = ref_int - ref_start_index; |
| 1428 | 1428 | const air_tags = air.instructions.items(.tag); |
| 1429 | 1429 | const air_datas = air.instructions.items(.data); |
| 1430 | assert(air_tags[inst_index] == .const_ty); | |
| 1431 | return air_datas[inst_index].ty; | |
| 1430 | return switch (air_tags[inst_index]) { | |
| 1431 | .const_ty => air_datas[inst_index].ty, | |
| 1432 | .interned => air_datas[inst_index].interned.toType(), | |
| 1433 | else => unreachable, | |
| 1434 | }; | |
| 1432 | 1435 | } |
| 1433 | 1436 | |
| 1434 | 1437 | /// Returns the requested data, as well as the new index which is at the start of the |
| ... | ... | @@ -1492,6 +1495,7 @@ pub fn value(air: Air, inst: Inst.Ref, mod: *const Module) ?Value { |
| 1492 | 1495 | switch (air.instructions.items(.tag)[inst_index]) { |
| 1493 | 1496 | .constant => return air.values[air_datas[inst_index].ty_pl.payload], |
| 1494 | 1497 | .const_ty => unreachable, |
| 1498 | .interned => return air_datas[inst_index].interned.toValue(), | |
| 1495 | 1499 | else => return air.typeOfIndex(inst_index, mod.intern_pool).onePossibleValue(mod), |
| 1496 | 1500 | } |
| 1497 | 1501 | } |
| ... | ... | @@ -1717,8 +1721,8 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: InternPool) bool { |
| 1717 | 1721 | => false, |
| 1718 | 1722 | |
| 1719 | 1723 | .assembly => @truncate(u1, air.extraData(Air.Asm, data.ty_pl.payload).data.flags >> 31) != 0, |
| 1720 | .load => air.typeOf(data.ty_op.operand, ip).isVolatilePtr(), | |
| 1721 | .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs, ip).isVolatilePtr(), | |
| 1722 | .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtr(), | |
| 1724 | .load => air.typeOf(data.ty_op.operand, ip).isVolatilePtrIp(ip), | |
| 1725 | .slice_elem_val, .ptr_elem_val => air.typeOf(data.bin_op.lhs, ip).isVolatilePtrIp(ip), | |
| 1726 | .atomic_load => air.typeOf(data.atomic_load.ptr, ip).isVolatilePtrIp(ip), | |
| 1723 | 1727 | }; |
| 1724 | 1728 | } |
src/InternPool.zig+29-12| ... | ... | @@ -73,7 +73,7 @@ pub const Key = union(enum) { |
| 73 | 73 | /// If zero use pointee_type.abiAlignment() |
| 74 | 74 | /// When creating pointer types, if alignment is equal to pointee type |
| 75 | 75 | /// abi alignment, this value should be set to 0 instead. |
| 76 | alignment: u16 = 0, | |
| 76 | alignment: u64 = 0, | |
| 77 | 77 | /// If this is non-zero it means the pointer points to a sub-byte |
| 78 | 78 | /// range of data, which is backed by a "host integer" with this |
| 79 | 79 | /// number of bytes. |
| ... | ... | @@ -90,9 +90,9 @@ pub const Key = union(enum) { |
| 90 | 90 | /// an appropriate value for this field. |
| 91 | 91 | address_space: std.builtin.AddressSpace = .generic, |
| 92 | 92 | |
| 93 | pub const VectorIndex = enum(u32) { | |
| 94 | none = std.math.maxInt(u32), | |
| 95 | runtime = std.math.maxInt(u32) - 1, | |
| 93 | pub const VectorIndex = enum(u16) { | |
| 94 | none = std.math.maxInt(u16), | |
| 95 | runtime = std.math.maxInt(u16) - 1, | |
| 96 | 96 | _, |
| 97 | 97 | }; |
| 98 | 98 | }; |
| ... | ... | @@ -806,16 +806,33 @@ pub const Pointer = struct { |
| 806 | 806 | sentinel: Index, |
| 807 | 807 | flags: Flags, |
| 808 | 808 | packed_offset: PackedOffset, |
| 809 | vector_index: VectorIndex, | |
| 809 | ||
| 810 | /// Stored as a power-of-two, with one special value to indicate none. | |
| 811 | pub const Alignment = enum(u6) { | |
| 812 | none = std.math.maxInt(u6), | |
| 813 | _, | |
| 814 | ||
| 815 | pub fn toByteUnits(a: Alignment, default: u64) u64 { | |
| 816 | return switch (a) { | |
| 817 | .none => default, | |
| 818 | _ => @as(u64, 1) << @enumToInt(a), | |
| 819 | }; | |
| 820 | } | |
| 821 | ||
| 822 | pub fn fromByteUnits(n: u64) Alignment { | |
| 823 | if (n == 0) return .none; | |
| 824 | return @intToEnum(Alignment, @ctz(n)); | |
| 825 | } | |
| 826 | }; | |
| 810 | 827 | |
| 811 | 828 | pub const Flags = packed struct(u32) { |
| 812 | alignment: u16, | |
| 829 | size: Size, | |
| 830 | alignment: Alignment, | |
| 813 | 831 | is_const: bool, |
| 814 | 832 | is_volatile: bool, |
| 815 | 833 | is_allowzero: bool, |
| 816 | size: Size, | |
| 817 | 834 | address_space: AddressSpace, |
| 818 | _: u7 = undefined, | |
| 835 | vector_index: VectorIndex, | |
| 819 | 836 | }; |
| 820 | 837 | |
| 821 | 838 | pub const PackedOffset = packed struct(u32) { |
| ... | ... | @@ -928,13 +945,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 928 | 945 | return .{ .ptr_type = .{ |
| 929 | 946 | .elem_type = ptr_info.child, |
| 930 | 947 | .sentinel = ptr_info.sentinel, |
| 931 | .alignment = ptr_info.flags.alignment, | |
| 948 | .alignment = ptr_info.flags.alignment.toByteUnits(0), | |
| 932 | 949 | .size = ptr_info.flags.size, |
| 933 | 950 | .is_const = ptr_info.flags.is_const, |
| 934 | 951 | .is_volatile = ptr_info.flags.is_volatile, |
| 935 | 952 | .is_allowzero = ptr_info.flags.is_allowzero, |
| 936 | 953 | .address_space = ptr_info.flags.address_space, |
| 937 | .vector_index = ptr_info.vector_index, | |
| 954 | .vector_index = ptr_info.flags.vector_index, | |
| 938 | 955 | .host_size = ptr_info.packed_offset.host_size, |
| 939 | 956 | .bit_offset = ptr_info.packed_offset.bit_offset, |
| 940 | 957 | } }; |
| ... | ... | @@ -1003,18 +1020,18 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 1003 | 1020 | .child = ptr_type.elem_type, |
| 1004 | 1021 | .sentinel = ptr_type.sentinel, |
| 1005 | 1022 | .flags = .{ |
| 1006 | .alignment = ptr_type.alignment, | |
| 1023 | .alignment = Pointer.Alignment.fromByteUnits(ptr_type.alignment), | |
| 1007 | 1024 | .is_const = ptr_type.is_const, |
| 1008 | 1025 | .is_volatile = ptr_type.is_volatile, |
| 1009 | 1026 | .is_allowzero = ptr_type.is_allowzero, |
| 1010 | 1027 | .size = ptr_type.size, |
| 1011 | 1028 | .address_space = ptr_type.address_space, |
| 1029 | .vector_index = ptr_type.vector_index, | |
| 1012 | 1030 | }, |
| 1013 | 1031 | .packed_offset = .{ |
| 1014 | 1032 | .host_size = ptr_type.host_size, |
| 1015 | 1033 | .bit_offset = ptr_type.bit_offset, |
| 1016 | 1034 | }, |
| 1017 | .vector_index = ptr_type.vector_index, | |
| 1018 | 1035 | }), |
| 1019 | 1036 | }); |
| 1020 | 1037 | }, |
src/Sema.zig+21-21| ... | ... | @@ -8400,7 +8400,7 @@ fn analyzeOptionalPayloadPtr( |
| 8400 | 8400 | const child_type = opt_type.optionalChild(mod); |
| 8401 | 8401 | const child_pointer = try Type.ptr(sema.arena, sema.mod, .{ |
| 8402 | 8402 | .pointee_type = child_type, |
| 8403 | .mutable = !optional_ptr_ty.isConstPtr(), | |
| 8403 | .mutable = !optional_ptr_ty.isConstPtr(mod), | |
| 8404 | 8404 | .@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod), |
| 8405 | 8405 | }); |
| 8406 | 8406 | |
| ... | ... | @@ -8594,7 +8594,7 @@ fn analyzeErrUnionPayloadPtr( |
| 8594 | 8594 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 8595 | 8595 | const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 8596 | 8596 | .pointee_type = payload_ty, |
| 8597 | .mutable = !operand_ty.isConstPtr(), | |
| 8597 | .mutable = !operand_ty.isConstPtr(mod), | |
| 8598 | 8598 | .@"addrspace" = operand_ty.ptrAddressSpace(mod), |
| 8599 | 8599 | }); |
| 8600 | 8600 | |
| ... | ... | @@ -10147,7 +10147,7 @@ fn zirSwitchCapture( |
| 10147 | 10147 | const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 10148 | 10148 | .pointee_type = field_ty, |
| 10149 | 10149 | .mutable = operand_ptr_ty.ptrIsMutable(mod), |
| 10150 | .@"volatile" = operand_ptr_ty.isVolatilePtr(), | |
| 10150 | .@"volatile" = operand_ptr_ty.isVolatilePtr(mod), | |
| 10151 | 10151 | .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod), |
| 10152 | 10152 | }); |
| 10153 | 10153 | return sema.addConstant( |
| ... | ... | @@ -10166,7 +10166,7 @@ fn zirSwitchCapture( |
| 10166 | 10166 | const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 10167 | 10167 | .pointee_type = field_ty, |
| 10168 | 10168 | .mutable = operand_ptr_ty.ptrIsMutable(mod), |
| 10169 | .@"volatile" = operand_ptr_ty.isVolatilePtr(), | |
| 10169 | .@"volatile" = operand_ptr_ty.isVolatilePtr(mod), | |
| 10170 | 10170 | .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod), |
| 10171 | 10171 | }); |
| 10172 | 10172 | return block.addStructFieldPtr(operand_ptr, field_index, ptr_field_ty); |
| ... | ... | @@ -15292,10 +15292,10 @@ fn zirCmpEq( |
| 15292 | 15292 | } |
| 15293 | 15293 | |
| 15294 | 15294 | // comparing null with optionals |
| 15295 | if (lhs_ty_tag == .Null and (rhs_ty_tag == .Optional or rhs_ty.isCPtr())) { | |
| 15295 | if (lhs_ty_tag == .Null and (rhs_ty_tag == .Optional or rhs_ty.isCPtr(mod))) { | |
| 15296 | 15296 | return sema.analyzeIsNull(block, src, rhs, op == .neq); |
| 15297 | 15297 | } |
| 15298 | if (rhs_ty_tag == .Null and (lhs_ty_tag == .Optional or lhs_ty.isCPtr())) { | |
| 15298 | if (rhs_ty_tag == .Null and (lhs_ty_tag == .Optional or lhs_ty.isCPtr(mod))) { | |
| 15299 | 15299 | return sema.analyzeIsNull(block, src, lhs, op == .neq); |
| 15300 | 15300 | } |
| 15301 | 15301 | |
| ... | ... | @@ -22254,7 +22254,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 22254 | 22254 | const target = sema.mod.getTarget(); |
| 22255 | 22255 | const mod = sema.mod; |
| 22256 | 22256 | |
| 22257 | if (dest_ty.isConstPtr()) { | |
| 22257 | if (dest_ty.isConstPtr(mod)) { | |
| 22258 | 22258 | return sema.fail(block, dest_src, "cannot memcpy to constant pointer", .{}); |
| 22259 | 22259 | } |
| 22260 | 22260 | |
| ... | ... | @@ -22452,7 +22452,7 @@ fn zirMemset(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void |
| 22452 | 22452 | const dest_ptr_ty = sema.typeOf(dest_ptr); |
| 22453 | 22453 | try checkMemOperand(sema, block, dest_src, dest_ptr_ty); |
| 22454 | 22454 | |
| 22455 | if (dest_ptr_ty.isConstPtr()) { | |
| 22455 | if (dest_ptr_ty.isConstPtr(mod)) { | |
| 22456 | 22456 | return sema.fail(block, dest_src, "cannot memset constant pointer", .{}); |
| 22457 | 22457 | } |
| 22458 | 22458 | |
| ... | ... | @@ -24206,7 +24206,7 @@ fn fieldPtr( |
| 24206 | 24206 | const result_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 24207 | 24207 | .pointee_type = slice_ptr_ty, |
| 24208 | 24208 | .mutable = attr_ptr_ty.ptrIsMutable(mod), |
| 24209 | .@"volatile" = attr_ptr_ty.isVolatilePtr(), | |
| 24209 | .@"volatile" = attr_ptr_ty.isVolatilePtr(mod), | |
| 24210 | 24210 | .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod), |
| 24211 | 24211 | }); |
| 24212 | 24212 | |
| ... | ... | @@ -24227,7 +24227,7 @@ fn fieldPtr( |
| 24227 | 24227 | const result_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 24228 | 24228 | .pointee_type = Type.usize, |
| 24229 | 24229 | .mutable = attr_ptr_ty.ptrIsMutable(mod), |
| 24230 | .@"volatile" = attr_ptr_ty.isVolatilePtr(), | |
| 24230 | .@"volatile" = attr_ptr_ty.isVolatilePtr(mod), | |
| 24231 | 24231 | .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod), |
| 24232 | 24232 | }); |
| 24233 | 24233 | |
| ... | ... | @@ -24897,7 +24897,7 @@ fn unionFieldPtr( |
| 24897 | 24897 | const ptr_field_ty = try Type.ptr(arena, sema.mod, .{ |
| 24898 | 24898 | .pointee_type = field.ty, |
| 24899 | 24899 | .mutable = union_ptr_ty.ptrIsMutable(mod), |
| 24900 | .@"volatile" = union_ptr_ty.isVolatilePtr(), | |
| 24900 | .@"volatile" = union_ptr_ty.isVolatilePtr(mod), | |
| 24901 | 24901 | .@"addrspace" = union_ptr_ty.ptrAddressSpace(mod), |
| 24902 | 24902 | }); |
| 24903 | 24903 | const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name).?); |
| ... | ... | @@ -25239,7 +25239,7 @@ fn tupleFieldPtr( |
| 25239 | 25239 | const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ |
| 25240 | 25240 | .pointee_type = field_ty, |
| 25241 | 25241 | .mutable = tuple_ptr_ty.ptrIsMutable(mod), |
| 25242 | .@"volatile" = tuple_ptr_ty.isVolatilePtr(), | |
| 25242 | .@"volatile" = tuple_ptr_ty.isVolatilePtr(mod), | |
| 25243 | 25243 | .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod), |
| 25244 | 25244 | }); |
| 25245 | 25245 | |
| ... | ... | @@ -25767,7 +25767,7 @@ fn coerceExtra( |
| 25767 | 25767 | } |
| 25768 | 25768 | |
| 25769 | 25769 | // coercion from C pointer |
| 25770 | if (inst_ty.isCPtr()) src_c_ptr: { | |
| 25770 | if (inst_ty.isCPtr(mod)) src_c_ptr: { | |
| 25771 | 25771 | if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :src_c_ptr; |
| 25772 | 25772 | // In this case we must add a safety check because the C pointer |
| 25773 | 25773 | // could be null. |
| ... | ... | @@ -27255,7 +27255,7 @@ fn storePtr2( |
| 27255 | 27255 | ) CompileError!void { |
| 27256 | 27256 | const mod = sema.mod; |
| 27257 | 27257 | const ptr_ty = sema.typeOf(ptr); |
| 27258 | if (ptr_ty.isConstPtr()) | |
| 27258 | if (ptr_ty.isConstPtr(mod)) | |
| 27259 | 27259 | return sema.fail(block, ptr_src, "cannot assign to constant", .{}); |
| 27260 | 27260 | |
| 27261 | 27261 | const elem_ty = ptr_ty.childType(mod); |
| ... | ... | @@ -29843,7 +29843,7 @@ fn analyzeSlice( |
| 29843 | 29843 | const result = try block.addBitCast(return_ty, new_ptr); |
| 29844 | 29844 | if (block.wantSafety()) { |
| 29845 | 29845 | // requirement: slicing C ptr is non-null |
| 29846 | if (ptr_ptr_child_ty.isCPtr()) { | |
| 29846 | if (ptr_ptr_child_ty.isCPtr(mod)) { | |
| 29847 | 29847 | const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true); |
| 29848 | 29848 | try sema.addSafetyCheck(block, is_non_null, .unwrap_null); |
| 29849 | 29849 | } |
| ... | ... | @@ -29902,7 +29902,7 @@ fn analyzeSlice( |
| 29902 | 29902 | try sema.requireRuntimeBlock(block, src, runtime_src); |
| 29903 | 29903 | if (block.wantSafety()) { |
| 29904 | 29904 | // requirement: slicing C ptr is non-null |
| 29905 | if (ptr_ptr_child_ty.isCPtr()) { | |
| 29905 | if (ptr_ptr_child_ty.isCPtr(mod)) { | |
| 29906 | 29906 | const is_non_null = try sema.analyzeIsNull(block, ptr_src, ptr, true); |
| 29907 | 29907 | try sema.addSafetyCheck(block, is_non_null, .unwrap_null); |
| 29908 | 29908 | } |
| ... | ... | @@ -30720,7 +30720,7 @@ fn resolvePeerTypes( |
| 30720 | 30720 | err_set_ty = try chosen_set_ty.errorSetMerge(sema.arena, candidate_set_ty); |
| 30721 | 30721 | } |
| 30722 | 30722 | } |
| 30723 | seen_const = seen_const or chosen_ty.isConstPtr(); | |
| 30723 | seen_const = seen_const or chosen_ty.isConstPtr(mod); | |
| 30724 | 30724 | chosen = candidate; |
| 30725 | 30725 | chosen_i = candidate_i + 1; |
| 30726 | 30726 | continue; |
| ... | ... | @@ -30876,12 +30876,12 @@ fn resolvePeerTypes( |
| 30876 | 30876 | .Optional => { |
| 30877 | 30877 | const opt_child_ty = candidate_ty.optionalChild(mod); |
| 30878 | 30878 | if ((try sema.coerceInMemoryAllowed(block, chosen_ty, opt_child_ty, false, target, src, src)) == .ok) { |
| 30879 | seen_const = seen_const or opt_child_ty.isConstPtr(); | |
| 30879 | seen_const = seen_const or opt_child_ty.isConstPtr(mod); | |
| 30880 | 30880 | any_are_null = true; |
| 30881 | 30881 | continue; |
| 30882 | 30882 | } |
| 30883 | 30883 | |
| 30884 | seen_const = seen_const or chosen_ty.isConstPtr(); | |
| 30884 | seen_const = seen_const or chosen_ty.isConstPtr(mod); | |
| 30885 | 30885 | any_are_null = false; |
| 30886 | 30886 | chosen = candidate; |
| 30887 | 30887 | chosen_i = candidate_i + 1; |
| ... | ... | @@ -30924,7 +30924,7 @@ fn resolvePeerTypes( |
| 30924 | 30924 | .Vector => continue, |
| 30925 | 30925 | else => {}, |
| 30926 | 30926 | }, |
| 30927 | .Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr() and chosen_ty.childType(mod).zigTypeTag(mod) == .Fn) { | |
| 30927 | .Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr(mod) and chosen_ty.childType(mod).zigTypeTag(mod) == .Fn) { | |
| 30928 | 30928 | if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(mod), candidate_ty, target, src, src)) { |
| 30929 | 30929 | continue; |
| 30930 | 30930 | } |
| ... | ... | @@ -31023,7 +31023,7 @@ fn resolvePeerTypes( |
| 31023 | 31023 | var info = chosen_ty.ptrInfo(mod); |
| 31024 | 31024 | info.sentinel = chosen_child_ty.sentinel(mod); |
| 31025 | 31025 | info.size = .Slice; |
| 31026 | info.mutable = !(seen_const or chosen_child_ty.isConstPtr()); | |
| 31026 | info.mutable = !(seen_const or chosen_child_ty.isConstPtr(mod)); | |
| 31027 | 31027 | info.pointee_type = chosen_child_ty.elemType2(mod); |
| 31028 | 31028 | |
| 31029 | 31029 | const new_ptr_ty = try Type.ptr(sema.arena, mod, info); |
src/arch/aarch64/CodeGen.zig+5-3| ... | ... | @@ -3430,9 +3430,10 @@ fn airPtrSlicePtrPtr(self: *Self, inst: Air.Inst.Index) !void { |
| 3430 | 3430 | } |
| 3431 | 3431 | |
| 3432 | 3432 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3433 | const mod = self.bin_file.options.module.?; | |
| 3433 | 3434 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 3434 | 3435 | const slice_ty = self.typeOf(bin_op.lhs); |
| 3435 | const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: { | |
| 3436 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | |
| 3436 | 3437 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 3437 | 3438 | const ptr_ty = slice_ty.slicePtrFieldType(&buf); |
| 3438 | 3439 | |
| ... | ... | @@ -3496,9 +3497,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3496 | 3497 | } |
| 3497 | 3498 | |
| 3498 | 3499 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 3500 | const mod = self.bin_file.options.module.?; | |
| 3499 | 3501 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 3500 | 3502 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3501 | const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: { | |
| 3503 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | |
| 3502 | 3504 | const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs }; |
| 3503 | 3505 | const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs }; |
| 3504 | 3506 | |
| ... | ... | @@ -3869,7 +3871,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 3869 | 3871 | break :result MCValue.none; |
| 3870 | 3872 | |
| 3871 | 3873 | const ptr = try self.resolveInst(ty_op.operand); |
| 3872 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(); | |
| 3874 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod); | |
| 3873 | 3875 | if (self.liveness.isUnused(inst) and !is_volatile) |
| 3874 | 3876 | break :result MCValue.dead; |
| 3875 | 3877 |
src/arch/arm/CodeGen.zig+5-3| ... | ... | @@ -2428,9 +2428,10 @@ fn ptrElemVal( |
| 2428 | 2428 | } |
| 2429 | 2429 | |
| 2430 | 2430 | fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2431 | const mod = self.bin_file.options.module.?; | |
| 2431 | 2432 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2432 | 2433 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2433 | const result: MCValue = if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: { | |
| 2434 | const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | |
| 2434 | 2435 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 2435 | 2436 | const ptr_ty = slice_ty.slicePtrFieldType(&buf); |
| 2436 | 2437 | |
| ... | ... | @@ -2527,9 +2528,10 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2527 | 2528 | } |
| 2528 | 2529 | |
| 2529 | 2530 | fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void { |
| 2531 | const mod = self.bin_file.options.module.?; | |
| 2530 | 2532 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2531 | 2533 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 2532 | const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: { | |
| 2534 | const result: MCValue = if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: { | |
| 2533 | 2535 | const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs }; |
| 2534 | 2536 | const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs }; |
| 2535 | 2537 | |
| ... | ... | @@ -2738,7 +2740,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 2738 | 2740 | break :result MCValue.none; |
| 2739 | 2741 | |
| 2740 | 2742 | const ptr = try self.resolveInst(ty_op.operand); |
| 2741 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(); | |
| 2743 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod); | |
| 2742 | 2744 | if (self.liveness.isUnused(inst) and !is_volatile) |
| 2743 | 2745 | break :result MCValue.dead; |
| 2744 | 2746 |
src/arch/riscv64/CodeGen.zig+1-1| ... | ... | @@ -1536,7 +1536,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1536 | 1536 | break :result MCValue.none; |
| 1537 | 1537 | |
| 1538 | 1538 | const ptr = try self.resolveInst(ty_op.operand); |
| 1539 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(); | |
| 1539 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod); | |
| 1540 | 1540 | if (self.liveness.isUnused(inst) and !is_volatile) |
| 1541 | 1541 | break :result MCValue.dead; |
| 1542 | 1542 |
src/arch/sparc64/CodeGen.zig+1-1| ... | ... | @@ -1827,7 +1827,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1827 | 1827 | break :result MCValue.none; |
| 1828 | 1828 | |
| 1829 | 1829 | const ptr = try self.resolveInst(ty_op.operand); |
| 1830 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(); | |
| 1830 | const is_volatile = self.typeOf(ty_op.operand).isVolatilePtr(mod); | |
| 1831 | 1831 | if (self.liveness.isUnused(inst) and !is_volatile) |
| 1832 | 1832 | break :result MCValue.dead; |
| 1833 | 1833 |
src/codegen/c.zig+6-6| ... | ... | @@ -6117,7 +6117,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 6117 | 6117 | try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor}); |
| 6118 | 6118 | try f.renderType(writer, ty); |
| 6119 | 6119 | try writer.writeByte(')'); |
| 6120 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | |
| 6120 | if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile"); | |
| 6121 | 6121 | try writer.writeAll(" *)"); |
| 6122 | 6122 | try f.writeCValue(writer, ptr, .Other); |
| 6123 | 6123 | try writer.writeAll(", "); |
| ... | ... | @@ -6159,7 +6159,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 6159 | 6159 | try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor}); |
| 6160 | 6160 | try f.renderType(writer, ty); |
| 6161 | 6161 | try writer.writeByte(')'); |
| 6162 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | |
| 6162 | if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile"); | |
| 6163 | 6163 | try writer.writeAll(" *)"); |
| 6164 | 6164 | try f.writeCValue(writer, ptr, .Other); |
| 6165 | 6165 | try writer.writeAll(", "); |
| ... | ... | @@ -6221,7 +6221,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6221 | 6221 | if (use_atomic) try writer.writeAll("zig_atomic("); |
| 6222 | 6222 | try f.renderType(writer, ty); |
| 6223 | 6223 | if (use_atomic) try writer.writeByte(')'); |
| 6224 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | |
| 6224 | if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile"); | |
| 6225 | 6225 | try writer.writeAll(" *)"); |
| 6226 | 6226 | try f.writeCValue(writer, ptr, .Other); |
| 6227 | 6227 | try writer.writeAll(", "); |
| ... | ... | @@ -6265,7 +6265,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6265 | 6265 | try writer.writeAll(", (zig_atomic("); |
| 6266 | 6266 | try f.renderType(writer, ty); |
| 6267 | 6267 | try writer.writeByte(')'); |
| 6268 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | |
| 6268 | if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile"); | |
| 6269 | 6269 | try writer.writeAll(" *)"); |
| 6270 | 6270 | try f.writeCValue(writer, ptr, .Other); |
| 6271 | 6271 | try writer.writeAll(", "); |
| ... | ... | @@ -6299,7 +6299,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa |
| 6299 | 6299 | try writer.writeAll("zig_atomic_store((zig_atomic("); |
| 6300 | 6300 | try f.renderType(writer, ty); |
| 6301 | 6301 | try writer.writeByte(')'); |
| 6302 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | |
| 6302 | if (ptr_ty.isVolatilePtr(mod)) try writer.writeAll(" volatile"); | |
| 6303 | 6303 | try writer.writeAll(" *)"); |
| 6304 | 6304 | try f.writeCValue(writer, ptr, .Other); |
| 6305 | 6305 | try writer.writeAll(", "); |
| ... | ... | @@ -6365,7 +6365,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { |
| 6365 | 6365 | return .none; |
| 6366 | 6366 | } |
| 6367 | 6367 | |
| 6368 | if (elem_abi_size > 1 or dest_ty.isVolatilePtr()) { | |
| 6368 | if (elem_abi_size > 1 or dest_ty.isVolatilePtr(mod)) { | |
| 6369 | 6369 | // For the assignment in this loop, the array pointer needs to get |
| 6370 | 6370 | // casted to a regular pointer, otherwise an error like this occurs: |
| 6371 | 6371 | // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable |
src/codegen/llvm.zig+5-5| ... | ... | @@ -7046,7 +7046,7 @@ pub const FuncGen = struct { |
| 7046 | 7046 | const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType(mod)); |
| 7047 | 7047 | const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, ""); |
| 7048 | 7048 | load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod)); |
| 7049 | load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr())); | |
| 7049 | load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr(mod))); | |
| 7050 | 7050 | break :blk load_inst; |
| 7051 | 7051 | }; |
| 7052 | 7052 | const modified_vector = self.builder.buildInsertElement(loaded_vector, operand, index, ""); |
| ... | ... | @@ -8221,7 +8221,7 @@ pub const FuncGen = struct { |
| 8221 | 8221 | const usize_llvm_ty = try self.dg.lowerType(Type.usize); |
| 8222 | 8222 | const len = usize_llvm_ty.constInt(operand_size, .False); |
| 8223 | 8223 | const dest_ptr_align = ptr_ty.ptrAlignment(mod); |
| 8224 | _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr()); | |
| 8224 | _ = self.builder.buildMemSet(dest_ptr, fill_byte, len, dest_ptr_align, ptr_ty.isVolatilePtr(mod)); | |
| 8225 | 8225 | if (safety and mod.comp.bin_file.options.valgrind) { |
| 8226 | 8226 | self.valgrindMarkUndef(dest_ptr, len); |
| 8227 | 8227 | } |
| ... | ... | @@ -8497,7 +8497,7 @@ pub const FuncGen = struct { |
| 8497 | 8497 | const dest_ptr_align = ptr_ty.ptrAlignment(mod); |
| 8498 | 8498 | const u8_llvm_ty = self.context.intType(8); |
| 8499 | 8499 | const dest_ptr = self.sliceOrArrayPtr(dest_slice, ptr_ty); |
| 8500 | const is_volatile = ptr_ty.isVolatilePtr(); | |
| 8500 | const is_volatile = ptr_ty.isVolatilePtr(mod); | |
| 8501 | 8501 | |
| 8502 | 8502 | if (self.air.value(bin_op.rhs, mod)) |elem_val| { |
| 8503 | 8503 | if (elem_val.isUndefDeep()) { |
| ... | ... | @@ -8621,7 +8621,7 @@ pub const FuncGen = struct { |
| 8621 | 8621 | const len = self.sliceOrArrayLenInBytes(dest_slice, dest_ptr_ty); |
| 8622 | 8622 | const dest_ptr = self.sliceOrArrayPtr(dest_slice, dest_ptr_ty); |
| 8623 | 8623 | const mod = self.dg.module; |
| 8624 | const is_volatile = src_ptr_ty.isVolatilePtr() or dest_ptr_ty.isVolatilePtr(); | |
| 8624 | const is_volatile = src_ptr_ty.isVolatilePtr(mod) or dest_ptr_ty.isVolatilePtr(mod); | |
| 8625 | 8625 | _ = self.builder.buildMemCpy( |
| 8626 | 8626 | dest_ptr, |
| 8627 | 8627 | dest_ptr_ty.ptrAlignment(mod), |
| ... | ... | @@ -9894,7 +9894,7 @@ pub const FuncGen = struct { |
| 9894 | 9894 | if (!info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) return null; |
| 9895 | 9895 | |
| 9896 | 9896 | const ptr_alignment = info.alignment(mod); |
| 9897 | const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr()); | |
| 9897 | const ptr_volatile = llvm.Bool.fromBool(ptr_ty.isVolatilePtr(mod)); | |
| 9898 | 9898 | |
| 9899 | 9899 | assert(info.vector_index != .runtime); |
| 9900 | 9900 | if (info.vector_index != .none) { |
src/codegen/spirv.zig+8-5| ... | ... | @@ -1689,7 +1689,7 @@ pub const DeclGen = struct { |
| 1689 | 1689 | const indirect_value_ty_ref = try self.resolveType(value_ty, .indirect); |
| 1690 | 1690 | const result_id = self.spv.allocId(); |
| 1691 | 1691 | const access = spec.MemoryAccess.Extended{ |
| 1692 | .Volatile = ptr_ty.isVolatilePtr(), | |
| 1692 | .Volatile = ptr_ty.isVolatilePtr(mod), | |
| 1693 | 1693 | }; |
| 1694 | 1694 | try self.func.body.emit(self.spv.gpa, .OpLoad, .{ |
| 1695 | 1695 | .id_result_type = self.typeId(indirect_value_ty_ref), |
| ... | ... | @@ -1705,7 +1705,7 @@ pub const DeclGen = struct { |
| 1705 | 1705 | const value_ty = ptr_ty.childType(mod); |
| 1706 | 1706 | const indirect_value_id = try self.convertToIndirect(value_ty, value_id); |
| 1707 | 1707 | const access = spec.MemoryAccess.Extended{ |
| 1708 | .Volatile = ptr_ty.isVolatilePtr(), | |
| 1708 | .Volatile = ptr_ty.isVolatilePtr(mod), | |
| 1709 | 1709 | }; |
| 1710 | 1710 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ |
| 1711 | 1711 | .pointer = ptr_id, |
| ... | ... | @@ -2464,9 +2464,10 @@ pub const DeclGen = struct { |
| 2464 | 2464 | } |
| 2465 | 2465 | |
| 2466 | 2466 | fn airSliceElemPtr(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2467 | const mod = self.module; | |
| 2467 | 2468 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2468 | 2469 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2469 | if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; | |
| 2470 | if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null; | |
| 2470 | 2471 | |
| 2471 | 2472 | const slice_id = try self.resolve(bin_op.lhs); |
| 2472 | 2473 | const index_id = try self.resolve(bin_op.rhs); |
| ... | ... | @@ -2479,9 +2480,10 @@ pub const DeclGen = struct { |
| 2479 | 2480 | } |
| 2480 | 2481 | |
| 2481 | 2482 | fn airSliceElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2483 | const mod = self.module; | |
| 2482 | 2484 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 2483 | 2485 | const slice_ty = self.typeOf(bin_op.lhs); |
| 2484 | if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; | |
| 2486 | if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null; | |
| 2485 | 2487 | |
| 2486 | 2488 | const slice_id = try self.resolve(bin_op.lhs); |
| 2487 | 2489 | const index_id = try self.resolve(bin_op.rhs); |
| ... | ... | @@ -2781,10 +2783,11 @@ pub const DeclGen = struct { |
| 2781 | 2783 | } |
| 2782 | 2784 | |
| 2783 | 2785 | fn airLoad(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| 2786 | const mod = self.module; | |
| 2784 | 2787 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 2785 | 2788 | const ptr_ty = self.typeOf(ty_op.operand); |
| 2786 | 2789 | const operand = try self.resolve(ty_op.operand); |
| 2787 | if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; | |
| 2790 | if (!ptr_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) return null; | |
| 2788 | 2791 | |
| 2789 | 2792 | return try self.load(ptr_ty, operand); |
| 2790 | 2793 | } |
src/type.zig+62-23| ... | ... | @@ -193,7 +193,7 @@ pub const Type = struct { |
| 193 | 193 | .Frame, |
| 194 | 194 | => false, |
| 195 | 195 | |
| 196 | .Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr()), | |
| 196 | .Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr(mod)), | |
| 197 | 197 | .Optional => { |
| 198 | 198 | if (!is_equality_cmp) return false; |
| 199 | 199 | return ty.optionalChild(mod).isSelfComparable(mod, is_equality_cmp); |
| ... | ... | @@ -3012,38 +3012,59 @@ pub const Type = struct { |
| 3012 | 3012 | } |
| 3013 | 3013 | } |
| 3014 | 3014 | |
| 3015 | pub fn isConstPtr(self: Type) bool { | |
| 3016 | return switch (self.tag()) { | |
| 3017 | .pointer => !self.castTag(.pointer).?.data.mutable, | |
| 3018 | else => false, | |
| 3015 | pub fn isConstPtr(ty: Type, mod: *const Module) bool { | |
| 3016 | return switch (ty.ip_index) { | |
| 3017 | .none => switch (ty.tag()) { | |
| 3018 | .pointer => !ty.castTag(.pointer).?.data.mutable, | |
| 3019 | else => false, | |
| 3020 | }, | |
| 3021 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 3022 | .ptr_type => |ptr_type| ptr_type.is_const, | |
| 3023 | else => false, | |
| 3024 | }, | |
| 3019 | 3025 | }; |
| 3020 | 3026 | } |
| 3021 | 3027 | |
| 3022 | pub fn isVolatilePtr(self: Type) bool { | |
| 3023 | return switch (self.tag()) { | |
| 3024 | .pointer => { | |
| 3025 | const payload = self.castTag(.pointer).?.data; | |
| 3026 | return payload.@"volatile"; | |
| 3028 | pub fn isVolatilePtr(ty: Type, mod: *const Module) bool { | |
| 3029 | return isVolatilePtrIp(ty, mod.intern_pool); | |
| 3030 | } | |
| 3031 | ||
| 3032 | pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool { | |
| 3033 | return switch (ty.ip_index) { | |
| 3034 | .none => switch (ty.tag()) { | |
| 3035 | .pointer => ty.castTag(.pointer).?.data.@"volatile", | |
| 3036 | else => false, | |
| 3037 | }, | |
| 3038 | else => switch (ip.indexToKey(ty.ip_index)) { | |
| 3039 | .ptr_type => |ptr_type| ptr_type.is_volatile, | |
| 3040 | else => false, | |
| 3027 | 3041 | }, |
| 3028 | else => false, | |
| 3029 | 3042 | }; |
| 3030 | 3043 | } |
| 3031 | 3044 | |
| 3032 | pub fn isAllowzeroPtr(self: Type, mod: *const Module) bool { | |
| 3033 | return switch (self.tag()) { | |
| 3034 | .pointer => { | |
| 3035 | const payload = self.castTag(.pointer).?.data; | |
| 3036 | return payload.@"allowzero"; | |
| 3045 | pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool { | |
| 3046 | return switch (ty.ip_index) { | |
| 3047 | .none => switch (ty.tag()) { | |
| 3048 | .pointer => ty.castTag(.pointer).?.data.@"allowzero", | |
| 3049 | else => ty.zigTypeTag(mod) == .Optional, | |
| 3050 | }, | |
| 3051 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 3052 | .ptr_type => |ptr_type| ptr_type.is_allowzero, | |
| 3053 | else => false, | |
| 3037 | 3054 | }, |
| 3038 | else => return self.zigTypeTag(mod) == .Optional, | |
| 3039 | 3055 | }; |
| 3040 | 3056 | } |
| 3041 | 3057 | |
| 3042 | pub fn isCPtr(self: Type) bool { | |
| 3043 | return switch (self.tag()) { | |
| 3044 | .pointer => self.castTag(.pointer).?.data.size == .C, | |
| 3045 | ||
| 3046 | else => return false, | |
| 3058 | pub fn isCPtr(ty: Type, mod: *const Module) bool { | |
| 3059 | return switch (ty.ip_index) { | |
| 3060 | .none => switch (ty.tag()) { | |
| 3061 | .pointer => ty.castTag(.pointer).?.data.size == .C, | |
| 3062 | else => false, | |
| 3063 | }, | |
| 3064 | else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { | |
| 3065 | .ptr_type => |ptr_type| ptr_type.size == .C, | |
| 3066 | else => false, | |
| 3067 | }, | |
| 3047 | 3068 | }; |
| 3048 | 3069 | } |
| 3049 | 3070 | |
| ... | ... | @@ -5063,7 +5084,7 @@ pub const Type = struct { |
| 5063 | 5084 | return .{ |
| 5064 | 5085 | .pointee_type = p.elem_type.toType(), |
| 5065 | 5086 | .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null, |
| 5066 | .@"align" = p.alignment, | |
| 5087 | .@"align" = @intCast(u32, p.alignment), | |
| 5067 | 5088 | .@"addrspace" = p.address_space, |
| 5068 | 5089 | .bit_offset = p.bit_offset, |
| 5069 | 5090 | .host_size = p.host_size, |
| ... | ... | @@ -5248,6 +5269,24 @@ pub const Type = struct { |
| 5248 | 5269 | } |
| 5249 | 5270 | } |
| 5250 | 5271 | |
| 5272 | if (d.pointee_type.ip_index != .none and | |
| 5273 | (d.sentinel == null or d.sentinel.?.ip_index != .none)) | |
| 5274 | { | |
| 5275 | return mod.ptrType(.{ | |
| 5276 | .elem_type = d.pointee_type.ip_index, | |
| 5277 | .sentinel = if (d.sentinel) |s| s.ip_index else .none, | |
| 5278 | .alignment = d.@"align", | |
| 5279 | .host_size = d.host_size, | |
| 5280 | .bit_offset = d.bit_offset, | |
| 5281 | .vector_index = d.vector_index, | |
| 5282 | .size = d.size, | |
| 5283 | .is_const = !d.mutable, | |
| 5284 | .is_volatile = d.@"volatile", | |
| 5285 | .is_allowzero = d.@"allowzero", | |
| 5286 | .address_space = d.@"addrspace", | |
| 5287 | }); | |
| 5288 | } | |
| 5289 | ||
| 5251 | 5290 | return Type.Tag.pointer.create(arena, d); |
| 5252 | 5291 | } |
| 5253 | 5292 |