[6.2] Fix deserialization of lifetime dependencies on ast function types

This commit is contained in:
Meghana Gupta
2025-06-02 16:23:22 -07:00
parent f45edab102
commit 637f8ef03e
6 changed files with 70 additions and 22 deletions

View File

@@ -231,6 +231,25 @@ public:
|| !conditionallyAddressableParamIndices
|| conditionallyAddressableParamIndices->isDisjointWith(
addressableParamIndices)));
if (CONDITIONAL_ASSERT_enabled()) {
// Ensure inherit/scope/addressable param indices are of the same length
// or 0.
unsigned paramIndicesLength = 0;
if (inheritLifetimeParamIndices) {
paramIndicesLength = inheritLifetimeParamIndices->getCapacity();
}
if (scopeLifetimeParamIndices) {
assert(paramIndicesLength == 0 ||
paramIndicesLength == scopeLifetimeParamIndices->getCapacity());
paramIndicesLength = scopeLifetimeParamIndices->getCapacity();
}
if (addressableParamIndices) {
assert(paramIndicesLength == 0 ||
paramIndicesLength == addressableParamIndices->getCapacity());
paramIndicesLength = addressableParamIndices->getCapacity();
}
}
}
operator bool() const { return !empty(); }
@@ -254,6 +273,19 @@ public:
return addressableParamIndicesAndImmortal.getPointer() != nullptr;
}
unsigned getParamIndicesLength() const {
if (hasInheritLifetimeParamIndices()) {
return getInheritIndices()->getCapacity();
}
if (hasScopeLifetimeParamIndices()) {
return getScopeIndices()->getCapacity();
}
if (hasAddressableParamIndices()) {
return getAddressableIndices()->getCapacity();
}
return 0;
}
IndexSubset *getInheritIndices() const { return inheritLifetimeParamIndices; }
IndexSubset *getScopeIndices() const { return scopeLifetimeParamIndices; }

View File

@@ -3846,7 +3846,7 @@ public:
ctor->setParameters(bodyParams);
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
while (auto info = MF.maybeReadLifetimeDependence(bodyParams->size() + 1)) {
while (auto info = MF.maybeReadLifetimeDependence()) {
assert(info.has_value());
lifetimeDependencies.push_back(*info);
}
@@ -4448,11 +4448,9 @@ public:
ParameterList *paramList;
SET_OR_RETURN_ERROR(paramList, MF.readParameterList());
fn->setParameters(paramList);
auto numParams =
fn->hasImplicitSelfDecl() ? paramList->size() + 1 : paramList->size();
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
while (auto info = MF.maybeReadLifetimeDependence(numParams)) {
while (auto info = MF.maybeReadLifetimeDependence()) {
assert(info.has_value());
lifetimeDependencies.push_back(*info);
}
@@ -7411,8 +7409,7 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
while (auto lifetimeDependence =
MF.maybeReadLifetimeDependence(params.size())) {
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence()) {
lifetimeDependencies.push_back(*lifetimeDependence);
}
if (!lifetimeDependencies.empty()) {
@@ -8062,7 +8059,7 @@ Expected<Type> DESERIALIZE_TYPE(SIL_FUNCTION_TYPE)(
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence(numParams)) {
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence()) {
lifetimeDependencies.push_back(*lifetimeDependence);
}
@@ -9348,7 +9345,7 @@ bool ModuleFile::maybeReadLifetimeDependenceRecord(
}
std::optional<LifetimeDependenceInfo>
ModuleFile::maybeReadLifetimeDependence(unsigned numParams) {
ModuleFile::maybeReadLifetimeDependence() {
using namespace decls_block;
SmallVector<uint64_t, 8> scratch;
@@ -9357,28 +9354,29 @@ ModuleFile::maybeReadLifetimeDependence(unsigned numParams) {
}
unsigned targetIndex;
unsigned paramIndicesLength;
bool isImmortal;
bool hasInheritLifetimeParamIndices;
bool hasScopeLifetimeParamIndices;
bool hasAddressableParamIndices;
ArrayRef<uint64_t> lifetimeDependenceData;
LifetimeDependenceLayout::readRecord(
scratch, targetIndex, isImmortal, hasInheritLifetimeParamIndices,
hasScopeLifetimeParamIndices, hasAddressableParamIndices,
lifetimeDependenceData);
scratch, targetIndex, paramIndicesLength, isImmortal,
hasInheritLifetimeParamIndices, hasScopeLifetimeParamIndices,
hasAddressableParamIndices, lifetimeDependenceData);
SmallBitVector inheritLifetimeParamIndices(numParams, false);
SmallBitVector scopeLifetimeParamIndices(numParams, false);
SmallBitVector addressableParamIndices(numParams, false);
SmallBitVector inheritLifetimeParamIndices(paramIndicesLength, false);
SmallBitVector scopeLifetimeParamIndices(paramIndicesLength, false);
SmallBitVector addressableParamIndices(paramIndicesLength, false);
unsigned startIndex = 0;
auto pushData = [&](SmallBitVector &bits) {
for (unsigned i = 0; i < numParams; i++) {
for (unsigned i = 0; i < paramIndicesLength; i++) {
if (lifetimeDependenceData[startIndex + i]) {
bits.set(i);
}
}
startIndex += numParams;
startIndex += paramIndicesLength;
};
if (hasInheritLifetimeParamIndices) {

View File

@@ -1105,8 +1105,7 @@ public:
bool maybeReadLifetimeDependenceRecord(SmallVectorImpl<uint64_t> &scratch);
// Reads lifetime dependence info from type if present.
std::optional<LifetimeDependenceInfo>
maybeReadLifetimeDependence(unsigned numParams);
std::optional<LifetimeDependenceInfo> maybeReadLifetimeDependence();
// Reads lifetime dependence specifier from decl if present
bool maybeReadLifetimeEntry(SmallVectorImpl<LifetimeEntry> &specifierList,

View File

@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
/// describe what change you made. The content of this comment isn't important;
/// it just ensures a conflict if two people change the module format.
/// Don't worry about adhering to the 80-column limit for this line.
const uint16_t SWIFTMODULE_VERSION_MINOR = 941; // add modifier to @_inheritActorContext
const uint16_t SWIFTMODULE_VERSION_MINOR = 942; // update LifetimeDependenceLayout
/// A standard hash seed used for all string hashes in a serialized module.
///
@@ -2317,6 +2317,7 @@ namespace decls_block {
using LifetimeDependenceLayout =
BCRecordLayout<LIFETIME_DEPENDENCE,
BCVBR<4>, // targetIndex
BCVBR<4>, // paramIndicesLength
BCFixed<1>, // isImmortal
BCFixed<1>, // hasInheritLifetimeParamIndices
BCFixed<1>, // hasScopeLifetimeParamIndices

View File

@@ -2738,10 +2738,10 @@ void Serializer::writeLifetimeDependencies(
auto abbrCode = DeclTypeAbbrCodes[LifetimeDependenceLayout::Code];
LifetimeDependenceLayout::emitRecord(
Out, ScratchRecord, abbrCode, info.getTargetIndex(), info.isImmortal(),
Out, ScratchRecord, abbrCode, info.getTargetIndex(),
info.getParamIndicesLength(), info.isImmortal(),
info.hasInheritLifetimeParamIndices(),
info.hasScopeLifetimeParamIndices(),
info.hasAddressableParamIndices(),
info.hasScopeLifetimeParamIndices(), info.hasAddressableParamIndices(),
paramIndices);
paramIndices.clear();
}

View File

@@ -0,0 +1,18 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module %s -o %t -enable-experimental-feature LifetimeDependence
// RUN: %target-swift-frontend -emit-sil %t/rdar151768216.swiftmodule \
// RUN: -enable-experimental-feature LifetimeDependence
// REQUIRES: swift_feature_LifetimeDependence
// Ensure no crash
extension Result {
@inlinable
func castError(i: Int, j: Int, k: Int) -> Result<Success, Failure> {
return self.mapError { error in
return error
}
}
}