diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-07-04 16:52:34 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-07-04 16:52:34 -0700 |
| commit | 9ecc47cd7cd5b5fbda8dc78a5d2ab41d8f0d01a8 (patch) | |
| tree | aadcb0b942205aaf703f57200c5110b3441b1182 /src/Sema.zig | |
| parent | eba8892b8495674e3d7d576dc6f9fb95e8dfa407 (diff) | |
| download | zig-9ecc47cd7cd5b5fbda8dc78a5d2ab41d8f0d01a8.tar.gz zig-9ecc47cd7cd5b5fbda8dc78a5d2ab41d8f0d01a8.zip | |
Sema: fix intFitsInType implementation
The function did not handle comptime_int in the case of lazy_align or
lazy_size.
Diffstat (limited to 'src/Sema.zig')
| -rw-r--r-- | src/Sema.zig | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 4c43746e57..e234255c6e 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -26080,12 +26080,12 @@ fn intFitsInType( sema: *Sema, block: *Block, src: LazySrcLoc, - self: Value, + val: Value, ty: Type, vector_index: ?*usize, ) CompileError!bool { const target = sema.mod.getTarget(); - switch (self.tag()) { + switch (val.tag()) { .zero, .undef, .bool_false, @@ -26105,30 +26105,38 @@ fn intFitsInType( else => unreachable, }, - .lazy_align => { - const info = ty.intInfo(target); - const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed); - // If it is u16 or bigger we know the alignment fits without resolving it. - if (info.bits >= max_needed_bits) return true; - const x = try sema.typeAbiAlignment(block, src, self.castTag(.lazy_align).?.data); - if (x == 0) return true; - const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); - return info.bits >= actual_needed_bits; + .lazy_align => switch (ty.zigTypeTag()) { + .Int => { + const info = ty.intInfo(target); + const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed); + // If it is u16 or bigger we know the alignment fits without resolving it. + if (info.bits >= max_needed_bits) return true; + const x = try sema.typeAbiAlignment(block, src, val.castTag(.lazy_align).?.data); + if (x == 0) return true; + const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); + return info.bits >= actual_needed_bits; + }, + .ComptimeInt => return true, + else => unreachable, }, - .lazy_size => { - const info = ty.intInfo(target); - const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed); - // If it is u64 or bigger we know the size fits without resolving it. - if (info.bits >= max_needed_bits) return true; - const x = try sema.typeAbiSize(block, src, self.castTag(.lazy_size).?.data); - if (x == 0) return true; - const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); - return info.bits >= actual_needed_bits; + .lazy_size => switch (ty.zigTypeTag()) { + .Int => { + const info = ty.intInfo(target); + const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed); + // If it is u64 or bigger we know the size fits without resolving it. + if (info.bits >= max_needed_bits) return true; + const x = try sema.typeAbiSize(block, src, val.castTag(.lazy_size).?.data); + if (x == 0) return true; + const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); + return info.bits >= actual_needed_bits; + }, + .ComptimeInt => return true, + else => unreachable, }, .int_u64 => switch (ty.zigTypeTag()) { .Int => { - const x = self.castTag(.int_u64).?.data; + const x = val.castTag(.int_u64).?.data; if (x == 0) return true; const info = ty.intInfo(target); const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed); @@ -26139,13 +26147,13 @@ fn intFitsInType( }, .int_i64 => switch (ty.zigTypeTag()) { .Int => { - const x = self.castTag(.int_i64).?.data; + const x = val.castTag(.int_i64).?.data; if (x == 0) return true; const info = ty.intInfo(target); if (info.signedness == .unsigned and x < 0) return false; var buffer: Value.BigIntSpace = undefined; - return (try self.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits); + return (try val.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits); }, .ComptimeInt => return true, else => unreachable, @@ -26153,7 +26161,7 @@ fn intFitsInType( .int_big_positive => switch (ty.zigTypeTag()) { .Int => { const info = ty.intInfo(target); - return self.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); + return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); }, .ComptimeInt => return true, else => unreachable, @@ -26161,7 +26169,7 @@ fn intFitsInType( .int_big_negative => switch (ty.zigTypeTag()) { .Int => { const info = ty.intInfo(target); - return self.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); + return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits); }, .ComptimeInt => return true, else => unreachable, @@ -26192,7 +26200,7 @@ fn intFitsInType( .aggregate => { assert(ty.zigTypeTag() == .Vector); - for (self.castTag(.aggregate).?.data) |elem, i| { + for (val.castTag(.aggregate).?.data) |elem, i| { if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) { if (vector_index) |some| some.* = i; return false; |
