@@ -908,19 +908,23 @@ class EnumTypeInfoBuilder {
908
908
Kind = RecordKind::SinglePayloadEnum;
909
909
addCase (PayloadCases[0 ].Name , CaseTR, CaseTI);
910
910
911
- // Below logic should match the runtime function
912
- // swift_initEnumValueWitnessTableSinglePayload().
913
- NumExtraInhabitants = CaseTI->getNumExtraInhabitants ();
914
- if (NumExtraInhabitants >= NoPayloadCases) {
915
- // Extra inhabitants can encode all no-payload cases.
916
- NumExtraInhabitants -= NoPayloadCases;
917
- } else {
918
- // Not enough extra inhabitants for all cases. We have to add an
919
- // extra tag field.
920
- NumExtraInhabitants = 0 ;
921
- Size += getNumTagBytes (Size,
922
- NoPayloadCases - NumExtraInhabitants,
923
- /* payloadCases=*/ 1 );
911
+ // If we were unable to lower the payload type, do not proceed
912
+ // further.
913
+ if (CaseTI != nullptr ) {
914
+ // Below logic should match the runtime function
915
+ // swift_initEnumValueWitnessTableSinglePayload().
916
+ NumExtraInhabitants = CaseTI->getNumExtraInhabitants ();
917
+ if (NumExtraInhabitants >= NoPayloadCases) {
918
+ // Extra inhabitants can encode all no-payload cases.
919
+ NumExtraInhabitants -= NoPayloadCases;
920
+ } else {
921
+ // Not enough extra inhabitants for all cases. We have to add an
922
+ // extra tag field.
923
+ NumExtraInhabitants = 0 ;
924
+ Size += getNumTagBytes (Size,
925
+ NoPayloadCases - NumExtraInhabitants,
926
+ /* payloadCases=*/ 1 );
927
+ }
924
928
}
925
929
926
930
// MultiPayloadEnumImplStrategy
@@ -1213,27 +1217,29 @@ class LowerType
1213
1217
}
1214
1218
1215
1219
const TypeInfo *visitOpaqueTypeRef (const OpaqueTypeRef *O) {
1216
- unreachable ( " Can't lower opaque TypeRef" );
1220
+ DEBUG (std::cerr << " Can't lower opaque TypeRef" );
1217
1221
return nullptr ;
1218
1222
}
1219
1223
};
1220
1224
1221
1225
const TypeInfo *TypeConverter::getTypeInfo (const TypeRef *TR) {
1226
+ // See if we already computed the result
1222
1227
auto found = Cache.find (TR);
1223
- if (found != Cache.end ()) {
1224
- auto *TI = found->second ;
1225
- assert (TI != nullptr && " TypeRef recursion detected" );
1226
- return TI;
1227
- }
1228
+ if (found != Cache.end ())
1229
+ return found->second ;
1228
1230
1229
- // Detect recursion
1230
- Cache[TR] = nullptr ;
1231
+ // Detect invalid recursive value types (IRGen should not emit
1232
+ // them in the first place, but there might be bugs)
1233
+ if (!RecursionCheck.insert (TR).second ) {
1234
+ DEBUG (std::cerr << " TypeRef recursion detected" );
1235
+ return nullptr ;
1236
+ }
1231
1237
1238
+ // Compute the result and cache it
1232
1239
auto *TI = LowerType (*this ).visit (TR);
1240
+ Cache[TR] = TI;
1233
1241
1234
- // Cache the result
1235
- if (TI != nullptr )
1236
- Cache[TR] = TI;
1242
+ RecursionCheck.erase (TR);
1237
1243
1238
1244
return TI;
1239
1245
}
0 commit comments