@@ -251,7 +251,7 @@ BuiltinTypeInfo::BuiltinTypeInfo(unsigned Size, unsigned Alignment,
251
251
252
252
// Builtin.Int<N> is mangled as 'Bi' N '_'
253
253
// Returns 0 if this isn't an Int
254
- static unsigned isIntType (std::string name) {
254
+ static unsigned intTypeBitSize (std::string name) {
255
255
llvm::StringRef nameRef (name);
256
256
if (nameRef.starts_with (" Bi" ) && nameRef.ends_with (" _" )) {
257
257
llvm::StringRef naturalRef = nameRef.drop_front (2 ).drop_back ();
@@ -272,23 +272,36 @@ bool BuiltinTypeInfo::readExtraInhabitantIndex(
272
272
*extraInhabitantIndex = -1 ;
273
273
return true ;
274
274
}
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
277
291
uint64_t maxValidValue = (((uint64_t )1 ) << intSize) - 1 ;
278
292
uint64_t maxAvailableValue = (((uint64_t )1 ) << (getSize () * 8 )) - 1 ;
279
293
uint64_t computedExtraInhabitants = maxAvailableValue - maxValidValue;
280
294
if (computedExtraInhabitants > ValueWitnessFlags::MaxNumExtraInhabitants) {
281
295
computedExtraInhabitants = ValueWitnessFlags::MaxNumExtraInhabitants;
282
296
}
283
297
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" );
285
299
300
+ // Example: maxValidValue is 1 for a 1-bit bool, so any larger value
301
+ // is an extra inhabitant.
286
302
uint64_t rawValue;
287
303
if (!reader.readInteger (address, getSize (), &rawValue))
288
304
return false ;
289
-
290
- // Example: maxValidValue is 1 for a 1-bit bool, so any larger value
291
- // is an extra inhabitant.
292
305
if (maxValidValue < rawValue) {
293
306
*extraInhabitantIndex = rawValue - maxValidValue - 1 ;
294
307
} else {
@@ -307,7 +320,7 @@ bool BuiltinTypeInfo::readExtraInhabitantIndex(
307
320
}
308
321
309
322
BitMask BuiltinTypeInfo::getSpareBits (TypeConverter &TC, bool &hasAddrOnly) const {
310
- unsigned intSize = isIntType (Name);
323
+ unsigned intSize = intTypeBitSize (Name);
311
324
if (intSize > 0 ) {
312
325
// Odd-sized integers export spare bits
313
326
// In particular: bool fields are Int1 and export 7 spare bits
0 commit comments