Skip to content

Commit 0cd9eb2

Browse files
committed
SIL: Fix incorrect type lowering behavior with multiple resilience expansions
When calling getTypeLowering() for the first time with a new type that did not appear in the cache under _any_ resilience expansion, we would incorrectly take the unlowered type and treat it as a lowered type, incorrectly skipping the computeLoweredRValueType() call.
1 parent a3d8d9c commit 0cd9eb2

File tree

2 files changed

+64
-67
lines changed

2 files changed

+64
-67
lines changed

include/swift/SIL/TypeLowering.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -697,11 +697,8 @@ class TypeConverter {
697697
const TypeLowering &
698698
getTypeLoweringForLoweredType(TypeKey key,
699699
ResilienceExpansion forExpansion);
700-
const TypeLowering &
701-
getTypeLoweringForUncachedLoweredType(TypeKey key,
702-
ResilienceExpansion forExpansion);
703700

704-
const TypeLowering &
701+
const TypeLowering *
705702
getTypeLoweringForExpansion(TypeKey key,
706703
ResilienceExpansion forExpansion,
707704
const TypeLowering *lowering);

lib/SIL/TypeLowering.cpp

Lines changed: 63 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,31 +1458,47 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
14581458
&& "dependent type outside of generic context?!");
14591459
assert(!substType->is<InOutType>());
14601460

1461-
if (auto existing = find(key))
1462-
return getTypeLoweringForExpansion(key, forExpansion, existing);
1461+
auto *prev = find(key);
1462+
auto *lowering = getTypeLoweringForExpansion(key, forExpansion, prev);
1463+
if (lowering != nullptr)
1464+
return *lowering;
1465+
1466+
#ifndef NDEBUG
1467+
// Catch reentrancy bugs.
1468+
if (prev == nullptr)
1469+
insert(key, nullptr);
1470+
#endif
14631471

14641472
// Lower the type.
1465-
CanType loweredSubstType =
1466-
computeLoweredRValueType(origType, substType);
1473+
auto loweredSubstType = computeLoweredRValueType(origType, substType);
14671474

14681475
// If that didn't change the type and the key is cacheable, there's no
14691476
// point in re-checking the table, so just construct a type lowering
14701477
// and cache it.
14711478
if (loweredSubstType == substType && key.isCacheable()) {
1472-
return getTypeLoweringForUncachedLoweredType(key, forExpansion);
1473-
}
1479+
lowering = LowerType(*this,
1480+
CanGenericSignature(),
1481+
forExpansion,
1482+
key.isDependent()).visit(key.SubstType);
14741483

14751484
// Otherwise, check the table at a key that would be used by the
14761485
// SILType-based lookup path for the type we just lowered to, then cache
14771486
// that same result at this key if possible.
1478-
AbstractionPattern origTypeForCaching =
1479-
AbstractionPattern(getCurGenericContext(), loweredSubstType);
1480-
auto loweredKey = getTypeKey(origTypeForCaching, loweredSubstType);
1481-
1482-
auto &lowering = getTypeLoweringForLoweredType(loweredKey,
1483-
forExpansion);
1484-
insert(key, &lowering);
1485-
return lowering;
1487+
} else {
1488+
AbstractionPattern origTypeForCaching =
1489+
AbstractionPattern(getCurGenericContext(), loweredSubstType);
1490+
auto loweredKey = getTypeKey(origTypeForCaching, loweredSubstType);
1491+
1492+
lowering = &getTypeLoweringForLoweredType(loweredKey,
1493+
forExpansion);
1494+
}
1495+
1496+
if (prev == nullptr)
1497+
insert(key, lowering);
1498+
else
1499+
prev->NextExpansion = lowering;
1500+
1501+
return *lowering;
14861502
}
14871503

14881504
CanType TypeConverter::computeLoweredRValueType(AbstractionPattern origType,
@@ -1611,73 +1627,57 @@ TypeConverter::getTypeLoweringForLoweredType(TypeKey key,
16111627
assert(type->isLegalSILType() && "type is not lowered!");
16121628
(void)type;
16131629

1614-
const TypeLowering *lowering = find(key);
1615-
if (!lowering)
1616-
lowering = &getTypeLoweringForUncachedLoweredType(key, forExpansion);
1630+
auto *prev = find(key);
1631+
auto *lowering = getTypeLoweringForExpansion(key, forExpansion, prev);
1632+
if (lowering != nullptr)
1633+
return *lowering;
1634+
1635+
#ifndef NDEBUG
1636+
// Catch reentrancy bugs.
1637+
if (prev == nullptr)
1638+
insert(key, nullptr);
1639+
#endif
1640+
1641+
lowering = LowerType(*this,
1642+
CanGenericSignature(),
1643+
forExpansion,
1644+
key.isDependent()).visit(key.SubstType);
16171645

1618-
return getTypeLoweringForExpansion(key, forExpansion, lowering);
1646+
if (prev)
1647+
prev->NextExpansion = lowering;
1648+
else
1649+
insert(key, lowering);
1650+
return *lowering;
16191651
}
16201652

16211653
/// When we've found a type lowering for one resilience expansion,
16221654
/// check if its the one we want; if not, walk the list until we
1623-
/// find the right one, or create a new lowering and add it to
1624-
/// the end of the list.
1625-
const TypeLowering & TypeConverter::
1655+
/// find the right one, returning nullptr if the caller needs to
1656+
/// go ahead and lower the type with the correct expansion.
1657+
const TypeLowering *TypeConverter::
16261658
getTypeLoweringForExpansion(TypeKey key,
16271659
ResilienceExpansion forExpansion,
16281660
const TypeLowering *lowering) {
1661+
if (lowering == nullptr)
1662+
return nullptr;
1663+
16291664
if (!lowering->isResilient()) {
16301665
// Don't try to refine the lowering for other resilience expansions if
16311666
// we don't expect to get a different lowering anyway.
1632-
return *lowering;
1667+
return lowering;
16331668
}
16341669

16351670
// Search for a matching lowering in the linked list of lowerings.
1636-
while (true) {
1671+
while (lowering) {
16371672
if (lowering->getResilienceExpansion() == forExpansion)
1638-
return *lowering;
1639-
if (lowering->NextExpansion) {
1640-
// Continue searching.
1641-
lowering = lowering->NextExpansion;
1642-
continue;
1643-
}
1644-
1645-
// Create a new lowering for the resilience expansion.
1646-
TypeLowering *theInfo = LowerType(*this,
1647-
CanGenericSignature(),
1648-
forExpansion,
1649-
key.isDependent()).visit(key.SubstType);
1673+
return lowering;
16501674

1651-
lowering->NextExpansion = theInfo;
1652-
return *theInfo;
1675+
// Continue searching.
1676+
lowering = lowering->NextExpansion;
16531677
}
1654-
}
1655-
1656-
/// Do type-lowering for a lowered type which is not already in the cache,
1657-
/// then insert it into the cache.
1658-
const TypeLowering & TypeConverter::
1659-
getTypeLoweringForUncachedLoweredType(TypeKey key,
1660-
ResilienceExpansion forExpansion) {
1661-
assert(!find(key) && "re-entrant or already cached");
1662-
assert(key.SubstType->isLegalSILType() && "type is not already lowered");
16631678

1664-
#ifndef NDEBUG
1665-
// Catch reentrancy bugs.
1666-
insert(key, nullptr);
1667-
#endif
1668-
1669-
auto *theInfo = LowerType(*this,
1670-
CanGenericSignature(),
1671-
forExpansion,
1672-
key.isDependent()).visit(key.SubstType);
1673-
1674-
if (key.OrigType.isForeign()) {
1675-
assert(theInfo->isLoadable() && "Cannot lower address-only type with "
1676-
"foreign abstraction pattern");
1677-
}
1678-
1679-
insert(key, theInfo);
1680-
return *theInfo;
1679+
// We have to create a new one.
1680+
return nullptr;
16811681
}
16821682

16831683
/// Get the type of a global variable accessor function, () -> RawPointer.

0 commit comments

Comments
 (0)