authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-04 16:52:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-04 16:52:34-07:00
log9ecc47cd7cd5b5fbda8dc78a5d2ab41d8f0d01a8
treeaadcb0b942205aaf703f57200c5110b3441b1182
parenteba8892b8495674e3d7d576dc6f9fb95e8dfa407

Sema: fix intFitsInType implementation

The function did not handle comptime_int in the case of lazy_align or lazy_size.

1 files changed, 34 insertions(+), 26 deletions(-)

src/Sema.zig+34-26
......@@ -26080,12 +26080,12 @@ fn intFitsInType(
2608026080 sema: *Sema,
2608126081 block: *Block,
2608226082 src: LazySrcLoc,
26083 self: Value,
26083 val: Value,
2608426084 ty: Type,
2608526085 vector_index: ?*usize,
2608626086) CompileError!bool {
2608726087 const target = sema.mod.getTarget();
26088 switch (self.tag()) {
26088 switch (val.tag()) {
2608926089 .zero,
2609026090 .undef,
2609126091 .bool_false,
......@@ -26105,30 +26105,38 @@ fn intFitsInType(
2610526105 else => unreachable,
2610626106 },
2610726107
26108 .lazy_align => {
26109 const info = ty.intInfo(target);
26110 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
26111 // If it is u16 or bigger we know the alignment fits without resolving it.
26112 if (info.bits >= max_needed_bits) return true;
26113 const x = try sema.typeAbiAlignment(block, src, self.castTag(.lazy_align).?.data);
26114 if (x == 0) return true;
26115 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
26116 return info.bits >= actual_needed_bits;
26108 .lazy_align => switch (ty.zigTypeTag()) {
26109 .Int => {
26110 const info = ty.intInfo(target);
26111 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
26112 // If it is u16 or bigger we know the alignment fits without resolving it.
26113 if (info.bits >= max_needed_bits) return true;
26114 const x = try sema.typeAbiAlignment(block, src, val.castTag(.lazy_align).?.data);
26115 if (x == 0) return true;
26116 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
26117 return info.bits >= actual_needed_bits;
26118 },
26119 .ComptimeInt => return true,
26120 else => unreachable,
2611726121 },
26118 .lazy_size => {
26119 const info = ty.intInfo(target);
26120 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
26121 // If it is u64 or bigger we know the size fits without resolving it.
26122 if (info.bits >= max_needed_bits) return true;
26123 const x = try sema.typeAbiSize(block, src, self.castTag(.lazy_size).?.data);
26124 if (x == 0) return true;
26125 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
26126 return info.bits >= actual_needed_bits;
26122 .lazy_size => switch (ty.zigTypeTag()) {
26123 .Int => {
26124 const info = ty.intInfo(target);
26125 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
26126 // If it is u64 or bigger we know the size fits without resolving it.
26127 if (info.bits >= max_needed_bits) return true;
26128 const x = try sema.typeAbiSize(block, src, val.castTag(.lazy_size).?.data);
26129 if (x == 0) return true;
26130 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
26131 return info.bits >= actual_needed_bits;
26132 },
26133 .ComptimeInt => return true,
26134 else => unreachable,
2612726135 },
2612826136
2612926137 .int_u64 => switch (ty.zigTypeTag()) {
2613026138 .Int => {
26131 const x = self.castTag(.int_u64).?.data;
26139 const x = val.castTag(.int_u64).?.data;
2613226140 if (x == 0) return true;
2613326141 const info = ty.intInfo(target);
2613426142 const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
......@@ -26139,13 +26147,13 @@ fn intFitsInType(
2613926147 },
2614026148 .int_i64 => switch (ty.zigTypeTag()) {
2614126149 .Int => {
26142 const x = self.castTag(.int_i64).?.data;
26150 const x = val.castTag(.int_i64).?.data;
2614326151 if (x == 0) return true;
2614426152 const info = ty.intInfo(target);
2614526153 if (info.signedness == .unsigned and x < 0)
2614626154 return false;
2614726155 var buffer: Value.BigIntSpace = undefined;
26148 return (try self.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits);
26156 return (try val.toBigIntAdvanced(&buffer, target, sema.kit(block, src))).fitsInTwosComp(info.signedness, info.bits);
2614926157 },
2615026158 .ComptimeInt => return true,
2615126159 else => unreachable,
......@@ -26153,7 +26161,7 @@ fn intFitsInType(
2615326161 .int_big_positive => switch (ty.zigTypeTag()) {
2615426162 .Int => {
2615526163 const info = ty.intInfo(target);
26156 return self.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
26164 return val.castTag(.int_big_positive).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
2615726165 },
2615826166 .ComptimeInt => return true,
2615926167 else => unreachable,
......@@ -26161,7 +26169,7 @@ fn intFitsInType(
2616126169 .int_big_negative => switch (ty.zigTypeTag()) {
2616226170 .Int => {
2616326171 const info = ty.intInfo(target);
26164 return self.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
26172 return val.castTag(.int_big_negative).?.asBigInt().fitsInTwosComp(info.signedness, info.bits);
2616526173 },
2616626174 .ComptimeInt => return true,
2616726175 else => unreachable,
......@@ -26192,7 +26200,7 @@ fn intFitsInType(
2619226200
2619326201 .aggregate => {
2619426202 assert(ty.zigTypeTag() == .Vector);
26195 for (self.castTag(.aggregate).?.data) |elem, i| {
26203 for (val.castTag(.aggregate).?.data) |elem, i| {
2619626204 if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) {
2619726205 if (vector_index) |some| some.* = i;
2619826206 return false;