Skip to content

Commit 346d5b2

Browse files
committed
Correct handling of nonsensical Int types
If an Int type makes no sense (it has a nonsensical number of extra inhabitants, for example), ignore it rather than treating it as a non-Int type. Rename `isIntType()` to `intTypeBitSize()` to better document what this function actually returns.
1 parent 40eb3c0 commit 346d5b2

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

stdlib/public/RemoteInspection/TypeLowering.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ BuiltinTypeInfo::BuiltinTypeInfo(unsigned Size, unsigned Alignment,
251251

252252
// Builtin.Int<N> is mangled as 'Bi' N '_'
253253
// Returns 0 if this isn't an Int
254-
static unsigned isIntType(std::string name) {
254+
static unsigned intTypeBitSize(std::string name) {
255255
llvm::StringRef nameRef(name);
256256
if (nameRef.starts_with("Bi") && nameRef.ends_with("_")) {
257257
llvm::StringRef naturalRef = nameRef.drop_front(2).drop_back();
@@ -272,23 +272,36 @@ bool BuiltinTypeInfo::readExtraInhabitantIndex(
272272
*extraInhabitantIndex = -1;
273273
return true;
274274
}
275-
unsigned intSize = isIntType(Name);
276-
if (intSize > 0 && intSize < 64 && getSize() <= 8 && intSize < getSize() * 8) {
275+
// If it has extra inhabitants, it could be an integer type with extra
276+
// inhabitants (such as a bool) or a pointer.
277+
unsigned intSize = intTypeBitSize(Name);
278+
if (intSize > 0) {
279+
// This is an integer type
280+
281+
// If extra inhabitants are impossible, return early...
282+
// (assert in debug builds)
283+
assert(intSize < getSize() * 8
284+
&& "Standard-sized int cannot have extra inhabitants");
285+
if (intSize > 64 || getSize() > 8 || intSize >= getSize() * 8) {
286+
*extraInhabitantIndex = -1;
287+
return true;
288+
}
289+
290+
// Compute range of extra inhabitants
277291
uint64_t maxValidValue = (((uint64_t)1) << intSize) - 1;
278292
uint64_t maxAvailableValue = (((uint64_t)1) << (getSize() * 8)) - 1;
279293
uint64_t computedExtraInhabitants = maxAvailableValue - maxValidValue;
280294
if (computedExtraInhabitants > ValueWitnessFlags::MaxNumExtraInhabitants) {
281295
computedExtraInhabitants = ValueWitnessFlags::MaxNumExtraInhabitants;
282296
}
283297
assert(getNumExtraInhabitants() == computedExtraInhabitants &&
284-
"Unexpected number of extra inhabitants in an odd-sized integer");
298+
"Unexpected number of extra inhabitants in an odd-sized integer");
285299

300+
// Example: maxValidValue is 1 for a 1-bit bool, so any larger value
301+
// is an extra inhabitant.
286302
uint64_t rawValue;
287303
if (!reader.readInteger(address, getSize(), &rawValue))
288304
return false;
289-
290-
// Example: maxValidValue is 1 for a 1-bit bool, so any larger value
291-
// is an extra inhabitant.
292305
if (maxValidValue < rawValue) {
293306
*extraInhabitantIndex = rawValue - maxValidValue - 1;
294307
} else {
@@ -307,7 +320,7 @@ bool BuiltinTypeInfo::readExtraInhabitantIndex(
307320
}
308321

309322
BitMask BuiltinTypeInfo::getSpareBits(TypeConverter &TC, bool &hasAddrOnly) const {
310-
unsigned intSize = isIntType(Name);
323+
unsigned intSize = intTypeBitSize(Name);
311324
if (intSize > 0) {
312325
// Odd-sized integers export spare bits
313326
// In particular: bool fields are Int1 and export 7 spare bits

0 commit comments

Comments
 (0)