mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[6.2] Fix deserialization of lifetime dependencies on ast function types
This commit is contained in:
@@ -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; }
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
18
validation-test/Serialization/rdar151768216.swift
Normal file
18
validation-test/Serialization/rdar151768216.swift
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user