authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-01-20 16:53:33+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-20 12:21:05-08:00
log2e7d28dd0d27d94945ac5f131d7f7b4e03bc0024
treec931e6021a9cd6c1ba1423235476f5d420073d99
parent10aff6750275bda834579b0b2daef14287d50438

Sema: replace uses of `toUnsignedInt` with `toUnsignedIntAdvanced`

During semantic analysis the value may be an unresolved lazy value which makes using `toUnsignedInt` invalid. Add assertions to detect similar issues in the future. Closes #18624

4 files changed, 51 insertions(+), 31 deletions(-)

src/Sema.zig+29-27
...@@ -3755,7 +3755,7 @@ fn resolveComptimeKnownAllocValue(sema: *Sema, block: *Block, alloc: Air.Inst.Re...@@ -3755,7 +3755,7 @@ fn resolveComptimeKnownAllocValue(sema: *Sema, block: *Block, alloc: Air.Inst.Re
3755 const idx_val = (try sema.resolveValue(data.rhs)).?;3755 const idx_val = (try sema.resolveValue(data.rhs)).?;
3756 break :blk .{3756 break :blk .{
3757 data.lhs,3757 data.lhs,
3758 .{ .elem = idx_val.toUnsignedInt(mod) },3758 .{ .elem = try idx_val.toUnsignedIntAdvanced(sema) },
3759 };3759 };
3760 },3760 },
3761 .bitcast => .{3761 .bitcast => .{
...@@ -8399,7 +8399,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8399,7 +8399,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8399 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);8399 const operand = try sema.coerce(block, err_int_ty, uncasted_operand, operand_src);
84008400
8401 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {8401 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8402 const int = try sema.usizeCast(block, operand_src, value.toUnsignedInt(mod));8402 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntAdvanced(sema));
8403 if (int > mod.global_error_set.count() or int == 0)8403 if (int > mod.global_error_set.count() or int == 0)
8404 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});8404 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
8405 return Air.internedToRef((try mod.intern(.{ .err = .{8405 return Air.internedToRef((try mod.intern(.{ .err = .{
...@@ -16522,7 +16522,7 @@ fn analyzePtrArithmetic(...@@ -16522,7 +16522,7 @@ fn analyzePtrArithmetic(
16522 // it being a multiple of the type size.16522 // it being a multiple of the type size.
16523 const elem_size = Type.fromInterned(ptr_info.child).abiSize(mod);16523 const elem_size = Type.fromInterned(ptr_info.child).abiSize(mod);
16524 const addend = if (opt_off_val) |off_val| a: {16524 const addend = if (opt_off_val) |off_val| a: {
16525 const off_int = try sema.usizeCast(block, offset_src, off_val.toUnsignedInt(mod));16525 const off_int = try sema.usizeCast(block, offset_src, try off_val.toUnsignedIntAdvanced(sema));
16526 break :a elem_size * off_int;16526 break :a elem_size * off_int;
16527 } else elem_size;16527 } else elem_size;
1652816528
...@@ -16554,7 +16554,7 @@ fn analyzePtrArithmetic(...@@ -16554,7 +16554,7 @@ fn analyzePtrArithmetic(
16554 if (opt_off_val) |offset_val| {16554 if (opt_off_val) |offset_val| {
16555 if (ptr_val.isUndef(mod)) return mod.undefRef(new_ptr_ty);16555 if (ptr_val.isUndef(mod)) return mod.undefRef(new_ptr_ty);
1655616556
16557 const offset_int = try sema.usizeCast(block, offset_src, offset_val.toUnsignedInt(mod));16557 const offset_int = try sema.usizeCast(block, offset_src, try offset_val.toUnsignedIntAdvanced(sema));
16558 if (offset_int == 0) return ptr;16558 if (offset_int == 0) return ptr;
16559 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {16559 if (try ptr_val.getUnsignedIntAdvanced(mod, sema)) |addr| {
16560 const elem_size = Type.fromInterned(ptr_info.child).abiSize(mod);16560 const elem_size = Type.fromInterned(ptr_info.child).abiSize(mod);
...@@ -20815,7 +20815,7 @@ fn zirReify(...@@ -20815,7 +20815,7 @@ fn zirReify(
20815 );20815 );
2081620816
20817 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);20817 const signedness = mod.toEnum(std.builtin.Signedness, signedness_val);
20818 const bits: u16 = @intCast(bits_val.toUnsignedInt(mod));20818 const bits: u16 = @intCast(try bits_val.toUnsignedIntAdvanced(sema));
20819 const ty = try mod.intType(signedness, bits);20819 const ty = try mod.intType(signedness, bits);
20820 return Air.internedToRef(ty.toIntern());20820 return Air.internedToRef(ty.toIntern());
20821 },20821 },
...@@ -20830,7 +20830,7 @@ fn zirReify(...@@ -20830,7 +20830,7 @@ fn zirReify(
20830 try ip.getOrPutString(gpa, "child"),20830 try ip.getOrPutString(gpa, "child"),
20831 ).?);20831 ).?);
2083220832
20833 const len: u32 = @intCast(len_val.toUnsignedInt(mod));20833 const len: u32 = @intCast(try len_val.toUnsignedIntAdvanced(sema));
20834 const child_ty = child_val.toType();20834 const child_ty = child_val.toType();
2083520835
20836 try sema.checkVectorElemType(block, src, child_ty);20836 try sema.checkVectorElemType(block, src, child_ty);
...@@ -20848,7 +20848,7 @@ fn zirReify(...@@ -20848,7 +20848,7 @@ fn zirReify(
20848 try ip.getOrPutString(gpa, "bits"),20848 try ip.getOrPutString(gpa, "bits"),
20849 ).?);20849 ).?);
2085020850
20851 const bits: u16 = @intCast(bits_val.toUnsignedInt(mod));20851 const bits: u16 = @intCast(try bits_val.toUnsignedIntAdvanced(sema));
20852 const ty = switch (bits) {20852 const ty = switch (bits) {
20853 16 => Type.f16,20853 16 => Type.f16,
20854 32 => Type.f32,20854 32 => Type.f32,
...@@ -20986,7 +20986,7 @@ fn zirReify(...@@ -20986,7 +20986,7 @@ fn zirReify(
20986 try ip.getOrPutString(gpa, "sentinel"),20986 try ip.getOrPutString(gpa, "sentinel"),
20987 ).?);20987 ).?);
2098820988
20989 const len = len_val.toUnsignedInt(mod);20989 const len = try len_val.toUnsignedIntAdvanced(sema);
20990 const child_ty = child_val.toType();20990 const child_ty = child_val.toType();
20991 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {20991 const sentinel = if (sentinel_val.optionalValue(mod)) |p| blk: {
20992 const ptr_ty = try mod.singleMutPtrType(child_ty);20992 const ptr_ty = try mod.singleMutPtrType(child_ty);
...@@ -21537,7 +21537,7 @@ fn zirReify(...@@ -21537,7 +21537,7 @@ fn zirReify(
21537 }21537 }
2153821538
21539 const alignment = alignment: {21539 const alignment = alignment: {
21540 const alignment = try sema.validateAlignAllowZero(block, src, alignment_val.toUnsignedInt(mod));21540 const alignment = try sema.validateAlignAllowZero(block, src, try alignment_val.toUnsignedIntAdvanced(sema));
21541 const default = target_util.defaultFunctionAlignment(target);21541 const default = target_util.defaultFunctionAlignment(target);
21542 break :alignment if (alignment == default) .none else alignment;21542 break :alignment if (alignment == default) .none else alignment;
21543 };21543 };
...@@ -22148,7 +22148,7 @@ fn ptrFromIntVal(...@@ -22148,7 +22148,7 @@ fn ptrFromIntVal(
22148 ptr_align: Alignment,22148 ptr_align: Alignment,
22149) !Value {22149) !Value {
22150 const mod = sema.mod;22150 const mod = sema.mod;
22151 const addr = operand_val.toUnsignedInt(mod);22151 const addr = try operand_val.toUnsignedIntAdvanced(sema);
22152 if (!ptr_ty.isAllowzeroPtr(mod) and addr == 0)22152 if (!ptr_ty.isAllowzeroPtr(mod) and addr == 0)
22153 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)});22153 return sema.fail(block, operand_src, "pointer type '{}' does not allow address zero", .{ptr_ty.fmt(sema.mod)});
22154 if (addr != 0 and ptr_align != .none and !ptr_align.check(addr))22154 if (addr != 0 and ptr_align != .none and !ptr_align.check(addr))
...@@ -23878,7 +23878,8 @@ fn analyzeShuffle(...@@ -23878,7 +23878,8 @@ fn analyzeShuffle(
23878 for (0..@intCast(mask_len)) |i| {23878 for (0..@intCast(mask_len)) |i| {
23879 const elem = try mask.elemValue(sema.mod, i);23879 const elem = try mask.elemValue(sema.mod, i);
23880 if (elem.isUndef(mod)) continue;23880 if (elem.isUndef(mod)) continue;
23881 const int = elem.toSignedInt(mod);23881 const elem_resolved = try sema.resolveLazyValue(elem);
23882 const int = elem_resolved.toSignedInt(mod);
23882 var unsigned: u32 = undefined;23883 var unsigned: u32 = undefined;
23883 var chosen: u32 = undefined;23884 var chosen: u32 = undefined;
23884 if (int >= 0) {23885 if (int >= 0) {
...@@ -24952,7 +24953,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void...@@ -24952,7 +24953,7 @@ fn zirMemcpy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void
24952 var new_dest_ptr = dest_ptr;24953 var new_dest_ptr = dest_ptr;
24953 var new_src_ptr = src_ptr;24954 var new_src_ptr = src_ptr;
24954 if (len_val) |val| {24955 if (len_val) |val| {
24955 const len = val.toUnsignedInt(mod);24956 const len = try val.toUnsignedIntAdvanced(sema);
24956 if (len == 0) {24957 if (len == 0) {
24957 // This AIR instruction guarantees length > 0 if it is comptime-known.24958 // This AIR instruction guarantees length > 0 if it is comptime-known.
24958 return;24959 return;
...@@ -25257,7 +25258,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25257,7 +25258,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25257 if (val.isGenericPoison()) {25258 if (val.isGenericPoison()) {
25258 break :blk null;25259 break :blk null;
25259 }25260 }
25260 const alignment = try sema.validateAlignAllowZero(block, align_src, val.toUnsignedInt(mod));25261 const alignment = try sema.validateAlignAllowZero(block, align_src, try val.toUnsignedIntAdvanced(sema));
25261 const default = target_util.defaultFunctionAlignment(target);25262 const default = target_util.defaultFunctionAlignment(target);
25262 break :blk if (alignment == default) .none else alignment;25263 break :blk if (alignment == default) .none else alignment;
25263 } else if (extra.data.bits.has_align_ref) blk: {25264 } else if (extra.data.bits.has_align_ref) blk: {
...@@ -25271,7 +25272,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A...@@ -25271,7 +25272,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
25271 },25272 },
25272 else => |e| return e,25273 else => |e| return e,
25273 };25274 };
25274 const alignment = try sema.validateAlignAllowZero(block, align_src, align_tv.val.toUnsignedInt(mod));25275 const alignment = try sema.validateAlignAllowZero(block, align_src, try align_tv.val.toUnsignedIntAdvanced(sema));
25275 const default = target_util.defaultFunctionAlignment(target);25276 const default = target_util.defaultFunctionAlignment(target);
25276 break :blk if (alignment == default) .none else alignment;25277 break :blk if (alignment == default) .none else alignment;
25277 } else .none;25278 } else .none;
...@@ -25569,7 +25570,7 @@ fn resolvePrefetchOptions(...@@ -25569,7 +25570,7 @@ fn resolvePrefetchOptions(
2556925570
25570 return std.builtin.PrefetchOptions{25571 return std.builtin.PrefetchOptions{
25571 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),25572 .rw = mod.toEnum(std.builtin.PrefetchOptions.Rw, rw_val),
25572 .locality = @intCast(locality_val.toUnsignedInt(mod)),25573 .locality = @intCast(try locality_val.toUnsignedIntAdvanced(sema)),
25573 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),25574 .cache = mod.toEnum(std.builtin.PrefetchOptions.Cache, cache_val),
25574 };25575 };
25575}25576}
...@@ -27757,7 +27758,7 @@ fn elemPtr(...@@ -27757,7 +27758,7 @@ fn elemPtr(
27757 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{27758 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
27758 .needed_comptime_reason = "tuple field access index must be comptime-known",27759 .needed_comptime_reason = "tuple field access index must be comptime-known",
27759 });27760 });
27760 const index: u32 = @intCast(index_val.toUnsignedInt(mod));27761 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));
27761 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);27762 break :blk try sema.tupleFieldPtr(block, src, indexable_ptr, elem_index_src, index, init);
27762 },27763 },
27763 else => {27764 else => {
...@@ -27795,7 +27796,7 @@ fn elemPtrOneLayerOnly(...@@ -27795,7 +27796,7 @@ fn elemPtrOneLayerOnly(
27795 const runtime_src = rs: {27796 const runtime_src = rs: {
27796 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;27797 const ptr_val = maybe_ptr_val orelse break :rs indexable_src;
27797 const index_val = maybe_index_val orelse break :rs elem_index_src;27798 const index_val = maybe_index_val orelse break :rs elem_index_src;
27798 const index: usize = @intCast(index_val.toUnsignedInt(mod));27799 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));
27799 const result_ty = try sema.elemPtrType(indexable_ty, index);27800 const result_ty = try sema.elemPtrType(indexable_ty, index);
27800 const elem_ptr = try ptr_val.elemPtr(result_ty, index, mod);27801 const elem_ptr = try ptr_val.elemPtr(result_ty, index, mod);
27801 return Air.internedToRef(elem_ptr.toIntern());27802 return Air.internedToRef(elem_ptr.toIntern());
...@@ -27814,7 +27815,7 @@ fn elemPtrOneLayerOnly(...@@ -27814,7 +27815,7 @@ fn elemPtrOneLayerOnly(
27814 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{27815 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
27815 .needed_comptime_reason = "tuple field access index must be comptime-known",27816 .needed_comptime_reason = "tuple field access index must be comptime-known",
27816 });27817 });
27817 const index: u32 = @intCast(index_val.toUnsignedInt(mod));27818 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));
27818 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);27819 break :blk try sema.tupleFieldPtr(block, indexable_src, indexable, elem_index_src, index, false);
27819 },27820 },
27820 else => unreachable, // Guaranteed by checkIndexable27821 else => unreachable, // Guaranteed by checkIndexable
...@@ -27854,7 +27855,7 @@ fn elemVal(...@@ -27854,7 +27855,7 @@ fn elemVal(
27854 const runtime_src = rs: {27855 const runtime_src = rs: {
27855 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;27856 const indexable_val = maybe_indexable_val orelse break :rs indexable_src;
27856 const index_val = maybe_index_val orelse break :rs elem_index_src;27857 const index_val = maybe_index_val orelse break :rs elem_index_src;
27857 const index: usize = @intCast(index_val.toUnsignedInt(mod));27858 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));
27858 const elem_ty = indexable_ty.elemType2(mod);27859 const elem_ty = indexable_ty.elemType2(mod);
27859 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);27860 const many_ptr_ty = try mod.manyConstPtrType(elem_ty);
27860 const many_ptr_val = try mod.getCoerced(indexable_val, many_ptr_ty);27861 const many_ptr_val = try mod.getCoerced(indexable_val, many_ptr_ty);
...@@ -27875,7 +27876,7 @@ fn elemVal(...@@ -27875,7 +27876,7 @@ fn elemVal(
27875 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;27876 if (inner_ty.zigTypeTag(mod) != .Array) break :arr_sent;
27876 const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent;27877 const sentinel = inner_ty.sentinel(mod) orelse break :arr_sent;
27877 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;27878 const index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index) orelse break :arr_sent;
27878 const index = try sema.usizeCast(block, src, index_val.toUnsignedInt(mod));27879 const index = try sema.usizeCast(block, src, try index_val.toUnsignedIntAdvanced(sema));
27879 if (index != inner_ty.arrayLen(mod)) break :arr_sent;27880 if (index != inner_ty.arrayLen(mod)) break :arr_sent;
27880 return Air.internedToRef(sentinel.toIntern());27881 return Air.internedToRef(sentinel.toIntern());
27881 }27882 }
...@@ -27893,7 +27894,7 @@ fn elemVal(...@@ -27893,7 +27894,7 @@ fn elemVal(
27893 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{27894 const index_val = try sema.resolveConstDefinedValue(block, elem_index_src, elem_index, .{
27894 .needed_comptime_reason = "tuple field access index must be comptime-known",27895 .needed_comptime_reason = "tuple field access index must be comptime-known",
27895 });27896 });
27896 const index: u32 = @intCast(index_val.toUnsignedInt(mod));27897 const index: u32 = @intCast(try index_val.toUnsignedIntAdvanced(sema));
27897 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);27898 return sema.tupleField(block, indexable_src, indexable, elem_index_src, index);
27898 },27899 },
27899 else => unreachable,27900 else => unreachable,
...@@ -28059,7 +28060,7 @@ fn elemValArray(...@@ -28059,7 +28060,7 @@ fn elemValArray(
28059 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);28060 const maybe_index_val = try sema.resolveDefinedValue(block, elem_index_src, elem_index);
2806028061
28061 if (maybe_index_val) |index_val| {28062 if (maybe_index_val) |index_val| {
28062 const index: usize = @intCast(index_val.toUnsignedInt(mod));28063 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));
28063 if (array_sent) |s| {28064 if (array_sent) |s| {
28064 if (index == array_len) {28065 if (index == array_len) {
28065 return Air.internedToRef(s.toIntern());28066 return Air.internedToRef(s.toIntern());
...@@ -28075,7 +28076,7 @@ fn elemValArray(...@@ -28075,7 +28076,7 @@ fn elemValArray(
28075 return mod.undefRef(elem_ty);28076 return mod.undefRef(elem_ty);
28076 }28077 }
28077 if (maybe_index_val) |index_val| {28078 if (maybe_index_val) |index_val| {
28078 const index: usize = @intCast(index_val.toUnsignedInt(mod));28079 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));
28079 const elem_val = try array_val.elemValue(mod, index);28080 const elem_val = try array_val.elemValue(mod, index);
28080 return Air.internedToRef(elem_val.toIntern());28081 return Air.internedToRef(elem_val.toIntern());
28081 }28082 }
...@@ -28122,7 +28123,7 @@ fn elemPtrArray(...@@ -28122,7 +28123,7 @@ fn elemPtrArray(
28122 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);28123 const maybe_undef_array_ptr_val = try sema.resolveValue(array_ptr);
28123 // The index must not be undefined since it can be out of bounds.28124 // The index must not be undefined since it can be out of bounds.
28124 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {28125 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
28125 const index = try sema.usizeCast(block, elem_index_src, index_val.toUnsignedInt(mod));28126 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntAdvanced(sema));
28126 if (index >= array_len_s) {28127 if (index >= array_len_s) {
28127 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";28128 const sentinel_label: []const u8 = if (array_sent) " +1 (sentinel)" else "";
28128 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });28129 return sema.fail(block, elem_index_src, "index {d} outside array of length {d}{s}", .{ index, array_len, sentinel_label });
...@@ -28188,7 +28189,7 @@ fn elemValSlice(...@@ -28188,7 +28189,7 @@ fn elemValSlice(
28188 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});28189 return sema.fail(block, slice_src, "indexing into empty slice is not allowed", .{});
28189 }28190 }
28190 if (maybe_index_val) |index_val| {28191 if (maybe_index_val) |index_val| {
28191 const index: usize = @intCast(index_val.toUnsignedInt(mod));28192 const index: usize = @intCast(try index_val.toUnsignedIntAdvanced(sema));
28192 if (index >= slice_len_s) {28193 if (index >= slice_len_s) {
28193 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";28194 const sentinel_label: []const u8 = if (slice_sent) " +1 (sentinel)" else "";
28194 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });28195 return sema.fail(block, elem_index_src, "index {d} outside slice of length {d}{s}", .{ index, slice_len, sentinel_label });
...@@ -28234,7 +28235,7 @@ fn elemPtrSlice(...@@ -28234,7 +28235,7 @@ fn elemPtrSlice(
28234 const maybe_undef_slice_val = try sema.resolveValue(slice);28235 const maybe_undef_slice_val = try sema.resolveValue(slice);
28235 // The index must not be undefined since it can be out of bounds.28236 // The index must not be undefined since it can be out of bounds.
28236 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {28237 const offset: ?usize = if (try sema.resolveDefinedValue(block, elem_index_src, elem_index)) |index_val| o: {
28237 const index = try sema.usizeCast(block, elem_index_src, index_val.toUnsignedInt(mod));28238 const index = try sema.usizeCast(block, elem_index_src, try index_val.toUnsignedIntAdvanced(sema));
28238 break :o index;28239 break :o index;
28239 } else null;28240 } else null;
2824028241
...@@ -32931,7 +32932,7 @@ fn analyzeSlice(...@@ -32931,7 +32932,7 @@ fn analyzeSlice(
32931 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;32932 const new_allowzero = new_ptr_ty_info.flags.is_allowzero and sema.typeOf(ptr).ptrSize(mod) != .C;
3293232933
32933 if (opt_new_len_val) |new_len_val| {32934 if (opt_new_len_val) |new_len_val| {
32934 const new_len_int = new_len_val.toUnsignedInt(mod);32935 const new_len_int = try new_len_val.toUnsignedIntAdvanced(sema);
3293532936
32936 const return_ty = try sema.ptrType(.{32937 const return_ty = try sema.ptrType(.{
32937 .child = (try mod.arrayType(.{32938 .child = (try mod.arrayType(.{
...@@ -36279,6 +36280,7 @@ fn semaStructFields(...@@ -36279,6 +36280,7 @@ fn semaStructFields(
36279 return;36280 return;
36280 },36281 },
36281 .Auto, .Extern => {36282 .Auto, .Extern => {
36283 struct_type.size(ip).* = 0;
36282 struct_type.flagsPtr(ip).layout_resolved = true;36284 struct_type.flagsPtr(ip).layout_resolved = true;
36283 return;36285 return;
36284 },36286 },
src/type.zig+8-4
...@@ -1380,12 +1380,15 @@ pub const Type = struct {...@@ -1380,12 +1380,15 @@ pub const Type = struct {
1380 },1380 },
1381 .eager => {},1381 .eager => {},
1382 }1382 }
1383 return switch (struct_type.layout) {1383 switch (struct_type.layout) {
1384 .Packed => .{1384 .Packed => return .{
1385 .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiSize(mod),1385 .scalar = Type.fromInterned(struct_type.backingIntType(ip).*).abiSize(mod),
1386 },1386 },
1387 .Auto, .Extern => .{ .scalar = struct_type.size(ip).* },1387 .Auto, .Extern => {
1388 };1388 assert(struct_type.haveLayout(ip));
1389 return .{ .scalar = struct_type.size(ip).* };
1390 },
1391 }
1389 },1392 },
1390 .anon_struct_type => |tuple| {1393 .anon_struct_type => |tuple| {
1391 switch (strat) {1394 switch (strat) {
...@@ -1411,6 +1414,7 @@ pub const Type = struct {...@@ -1411,6 +1414,7 @@ pub const Type = struct {
1411 .eager => {},1414 .eager => {},
1412 }1415 }
14131416
1417 assert(union_type.haveLayout(ip));
1414 return .{ .scalar = union_type.size(ip).* };1418 return .{ .scalar = union_type.size(ip).* };
1415 },1419 },
1416 .opaque_type => unreachable, // no size available1420 .opaque_type => unreachable, // no size available
src/value.zig+5
...@@ -575,6 +575,11 @@ pub const Value = struct {...@@ -575,6 +575,11 @@ pub const Value = struct {
575 return getUnsignedInt(val, mod).?;575 return getUnsignedInt(val, mod).?;
576 }576 }
577577
578 /// Asserts the value is an integer and it fits in a u64
579 pub fn toUnsignedIntAdvanced(val: Value, sema: *Sema) !u64 {
580 return (try getUnsignedIntAdvanced(val, sema.mod, sema)).?;
581 }
582
578 /// Asserts the value is an integer and it fits in a i64583 /// Asserts the value is an integer and it fits in a i64
579 pub fn toSignedInt(val: Value, mod: *Module) i64 {584 pub fn toSignedInt(val: Value, mod: *Module) i64 {
580 return switch (val.toIntern()) {585 return switch (val.toIntern()) {
test/behavior/sizeof_and_typeof.zig+9
...@@ -429,3 +429,12 @@ test "Extern function calls, dereferences and field access in @TypeOf" {...@@ -429,3 +429,12 @@ test "Extern function calls, dereferences and field access in @TypeOf" {
429 try Test.doTheTest();429 try Test.doTheTest();
430 try comptime Test.doTheTest();430 try comptime Test.doTheTest();
431}431}
432
433test "@sizeOf struct is resolved when used as operand of slicing" {
434 const dummy = struct {};
435 const S = struct {
436 var buf: [1]u8 = undefined;
437 };
438 S.buf[@sizeOf(dummy)..][0] = 0;
439 try expect(S.buf[0] == 0);
440}