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(...@@ -26080,12 +26080,12 @@ fn intFitsInType(
26080 sema: *Sema,26080 sema: *Sema,
26081 block: *Block,26081 block: *Block,
26082 src: LazySrcLoc,26082 src: LazySrcLoc,
26083 self: Value,26083 val: Value,
26084 ty: Type,26084 ty: Type,
26085 vector_index: ?*usize,26085 vector_index: ?*usize,
26086) CompileError!bool {26086) CompileError!bool {
26087 const target = sema.mod.getTarget();26087 const target = sema.mod.getTarget();
26088 switch (self.tag()) {26088 switch (val.tag()) {
26089 .zero,26089 .zero,
26090 .undef,26090 .undef,
26091 .bool_false,26091 .bool_false,
...@@ -26105,30 +26105,38 @@ fn intFitsInType(...@@ -26105,30 +26105,38 @@ fn intFitsInType(
26105 else => unreachable,26105 else => unreachable,
26106 },26106 },
2610726107
26108 .lazy_align => {26108 .lazy_align => switch (ty.zigTypeTag()) {
26109 const info = ty.intInfo(target);26109 .Int => {
26110 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);26110 const info = ty.intInfo(target);
26111 // If it is u16 or bigger we know the alignment fits without resolving it.26111 const max_needed_bits = @as(u16, 16) + @boolToInt(info.signedness == .signed);
26112 if (info.bits >= max_needed_bits) return true;26112 // If it is u16 or bigger we know the alignment fits without resolving it.
26113 const x = try sema.typeAbiAlignment(block, src, self.castTag(.lazy_align).?.data);26113 if (info.bits >= max_needed_bits) return true;
26114 if (x == 0) return true;26114 const x = try sema.typeAbiAlignment(block, src, val.castTag(.lazy_align).?.data);
26115 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);26115 if (x == 0) return true;
26116 return info.bits >= actual_needed_bits;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,
26117 },26121 },
26118 .lazy_size => {26122 .lazy_size => switch (ty.zigTypeTag()) {
26119 const info = ty.intInfo(target);26123 .Int => {
26120 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);26124 const info = ty.intInfo(target);
26121 // If it is u64 or bigger we know the size fits without resolving it.26125 const max_needed_bits = @as(u16, 64) + @boolToInt(info.signedness == .signed);
26122 if (info.bits >= max_needed_bits) return true;26126 // If it is u64 or bigger we know the size fits without resolving it.
26123 const x = try sema.typeAbiSize(block, src, self.castTag(.lazy_size).?.data);26127 if (info.bits >= max_needed_bits) return true;
26124 if (x == 0) return true;26128 const x = try sema.typeAbiSize(block, src, val.castTag(.lazy_size).?.data);
26125 const actual_needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);26129 if (x == 0) return true;
26126 return info.bits >= actual_needed_bits;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,
26127 },26135 },
2612826136
26129 .int_u64 => switch (ty.zigTypeTag()) {26137 .int_u64 => switch (ty.zigTypeTag()) {
26130 .Int => {26138 .Int => {
26131 const x = self.castTag(.int_u64).?.data;26139 const x = val.castTag(.int_u64).?.data;
26132 if (x == 0) return true;26140 if (x == 0) return true;
26133 const info = ty.intInfo(target);26141 const info = ty.intInfo(target);
26134 const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);26142 const needed_bits = std.math.log2(x) + 1 + @boolToInt(info.signedness == .signed);
...@@ -26139,13 +26147,13 @@ fn intFitsInType(...@@ -26139,13 +26147,13 @@ fn intFitsInType(
26139 },26147 },
26140 .int_i64 => switch (ty.zigTypeTag()) {26148 .int_i64 => switch (ty.zigTypeTag()) {
26141 .Int => {26149 .Int => {
26142 const x = self.castTag(.int_i64).?.data;26150 const x = val.castTag(.int_i64).?.data;
26143 if (x == 0) return true;26151 if (x == 0) return true;
26144 const info = ty.intInfo(target);26152 const info = ty.intInfo(target);
26145 if (info.signedness == .unsigned and x < 0)26153 if (info.signedness == .unsigned and x < 0)
26146 return false;26154 return false;
26147 var buffer: Value.BigIntSpace = undefined;26155 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);
26149 },26157 },
26150 .ComptimeInt => return true,26158 .ComptimeInt => return true,
26151 else => unreachable,26159 else => unreachable,
...@@ -26153,7 +26161,7 @@ fn intFitsInType(...@@ -26153,7 +26161,7 @@ fn intFitsInType(
26153 .int_big_positive => switch (ty.zigTypeTag()) {26161 .int_big_positive => switch (ty.zigTypeTag()) {
26154 .Int => {26162 .Int => {
26155 const info = ty.intInfo(target);26163 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);
26157 },26165 },
26158 .ComptimeInt => return true,26166 .ComptimeInt => return true,
26159 else => unreachable,26167 else => unreachable,
...@@ -26161,7 +26169,7 @@ fn intFitsInType(...@@ -26161,7 +26169,7 @@ fn intFitsInType(
26161 .int_big_negative => switch (ty.zigTypeTag()) {26169 .int_big_negative => switch (ty.zigTypeTag()) {
26162 .Int => {26170 .Int => {
26163 const info = ty.intInfo(target);26171 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);
26165 },26173 },
26166 .ComptimeInt => return true,26174 .ComptimeInt => return true,
26167 else => unreachable,26175 else => unreachable,
...@@ -26192,7 +26200,7 @@ fn intFitsInType(...@@ -26192,7 +26200,7 @@ fn intFitsInType(
2619226200
26193 .aggregate => {26201 .aggregate => {
26194 assert(ty.zigTypeTag() == .Vector);26202 assert(ty.zigTypeTag() == .Vector);
26195 for (self.castTag(.aggregate).?.data) |elem, i| {26203 for (val.castTag(.aggregate).?.data) |elem, i| {
26196 if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) {26204 if (!(try sema.intFitsInType(block, src, elem, ty.scalarType(), null))) {
26197 if (vector_index) |some| some.* = i;26205 if (vector_index) |some| some.* = i;
26198 return false;26206 return false;