Skip to content

Commit 637f8ef

Browse files
committed
[6.2] Fix deserialization of lifetime dependencies on ast function types
1 parent f45edab commit 637f8ef

File tree

6 files changed

+70
-22
lines changed

6 files changed

+70
-22
lines changed

include/swift/AST/LifetimeDependence.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,25 @@ class LifetimeDependenceInfo {
231231
|| !conditionallyAddressableParamIndices
232232
|| conditionallyAddressableParamIndices->isDisjointWith(
233233
addressableParamIndices)));
234+
235+
if (CONDITIONAL_ASSERT_enabled()) {
236+
// Ensure inherit/scope/addressable param indices are of the same length
237+
// or 0.
238+
unsigned paramIndicesLength = 0;
239+
if (inheritLifetimeParamIndices) {
240+
paramIndicesLength = inheritLifetimeParamIndices->getCapacity();
241+
}
242+
if (scopeLifetimeParamIndices) {
243+
assert(paramIndicesLength == 0 ||
244+
paramIndicesLength == scopeLifetimeParamIndices->getCapacity());
245+
paramIndicesLength = scopeLifetimeParamIndices->getCapacity();
246+
}
247+
if (addressableParamIndices) {
248+
assert(paramIndicesLength == 0 ||
249+
paramIndicesLength == addressableParamIndices->getCapacity());
250+
paramIndicesLength = addressableParamIndices->getCapacity();
251+
}
252+
}
234253
}
235254

236255
operator bool() const { return !empty(); }
@@ -254,6 +273,19 @@ class LifetimeDependenceInfo {
254273
return addressableParamIndicesAndImmortal.getPointer() != nullptr;
255274
}
256275

276+
unsigned getParamIndicesLength() const {
277+
if (hasInheritLifetimeParamIndices()) {
278+
return getInheritIndices()->getCapacity();
279+
}
280+
if (hasScopeLifetimeParamIndices()) {
281+
return getScopeIndices()->getCapacity();
282+
}
283+
if (hasAddressableParamIndices()) {
284+
return getAddressableIndices()->getCapacity();
285+
}
286+
return 0;
287+
}
288+
257289
IndexSubset *getInheritIndices() const { return inheritLifetimeParamIndices; }
258290

259291
IndexSubset *getScopeIndices() const { return scopeLifetimeParamIndices; }

lib/Serialization/Deserialization.cpp

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3846,7 +3846,7 @@ class DeclDeserializer {
38463846
ctor->setParameters(bodyParams);
38473847

38483848
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
3849-
while (auto info = MF.maybeReadLifetimeDependence(bodyParams->size() + 1)) {
3849+
while (auto info = MF.maybeReadLifetimeDependence()) {
38503850
assert(info.has_value());
38513851
lifetimeDependencies.push_back(*info);
38523852
}
@@ -4448,11 +4448,9 @@ class DeclDeserializer {
44484448
ParameterList *paramList;
44494449
SET_OR_RETURN_ERROR(paramList, MF.readParameterList());
44504450
fn->setParameters(paramList);
4451-
auto numParams =
4452-
fn->hasImplicitSelfDecl() ? paramList->size() + 1 : paramList->size();
44534451

44544452
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
4455-
while (auto info = MF.maybeReadLifetimeDependence(numParams)) {
4453+
while (auto info = MF.maybeReadLifetimeDependence()) {
44564454
assert(info.has_value());
44574455
lifetimeDependencies.push_back(*info);
44584456
}
@@ -7411,8 +7409,7 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
74117409

74127410
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
74137411

7414-
while (auto lifetimeDependence =
7415-
MF.maybeReadLifetimeDependence(params.size())) {
7412+
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence()) {
74167413
lifetimeDependencies.push_back(*lifetimeDependence);
74177414
}
74187415
if (!lifetimeDependencies.empty()) {
@@ -8062,7 +8059,7 @@ Expected<Type> DESERIALIZE_TYPE(SIL_FUNCTION_TYPE)(
80628059

80638060
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
80648061

8065-
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence(numParams)) {
8062+
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence()) {
80668063
lifetimeDependencies.push_back(*lifetimeDependence);
80678064
}
80688065

@@ -9348,7 +9345,7 @@ bool ModuleFile::maybeReadLifetimeDependenceRecord(
93489345
}
93499346

93509347
std::optional<LifetimeDependenceInfo>
9351-
ModuleFile::maybeReadLifetimeDependence(unsigned numParams) {
9348+
ModuleFile::maybeReadLifetimeDependence() {
93529349
using namespace decls_block;
93539350

93549351
SmallVector<uint64_t, 8> scratch;
@@ -9357,28 +9354,29 @@ ModuleFile::maybeReadLifetimeDependence(unsigned numParams) {
93579354
}
93589355

93599356
unsigned targetIndex;
9357+
unsigned paramIndicesLength;
93609358
bool isImmortal;
93619359
bool hasInheritLifetimeParamIndices;
93629360
bool hasScopeLifetimeParamIndices;
93639361
bool hasAddressableParamIndices;
93649362
ArrayRef<uint64_t> lifetimeDependenceData;
93659363
LifetimeDependenceLayout::readRecord(
9366-
scratch, targetIndex, isImmortal, hasInheritLifetimeParamIndices,
9367-
hasScopeLifetimeParamIndices, hasAddressableParamIndices,
9368-
lifetimeDependenceData);
9364+
scratch, targetIndex, paramIndicesLength, isImmortal,
9365+
hasInheritLifetimeParamIndices, hasScopeLifetimeParamIndices,
9366+
hasAddressableParamIndices, lifetimeDependenceData);
93699367

9370-
SmallBitVector inheritLifetimeParamIndices(numParams, false);
9371-
SmallBitVector scopeLifetimeParamIndices(numParams, false);
9372-
SmallBitVector addressableParamIndices(numParams, false);
9368+
SmallBitVector inheritLifetimeParamIndices(paramIndicesLength, false);
9369+
SmallBitVector scopeLifetimeParamIndices(paramIndicesLength, false);
9370+
SmallBitVector addressableParamIndices(paramIndicesLength, false);
93739371

93749372
unsigned startIndex = 0;
93759373
auto pushData = [&](SmallBitVector &bits) {
9376-
for (unsigned i = 0; i < numParams; i++) {
9374+
for (unsigned i = 0; i < paramIndicesLength; i++) {
93779375
if (lifetimeDependenceData[startIndex + i]) {
93789376
bits.set(i);
93799377
}
93809378
}
9381-
startIndex += numParams;
9379+
startIndex += paramIndicesLength;
93829380
};
93839381

93849382
if (hasInheritLifetimeParamIndices) {

lib/Serialization/ModuleFile.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,8 +1105,7 @@ class ModuleFile
11051105
bool maybeReadLifetimeDependenceRecord(SmallVectorImpl<uint64_t> &scratch);
11061106

11071107
// Reads lifetime dependence info from type if present.
1108-
std::optional<LifetimeDependenceInfo>
1109-
maybeReadLifetimeDependence(unsigned numParams);
1108+
std::optional<LifetimeDependenceInfo> maybeReadLifetimeDependence();
11101109

11111110
// Reads lifetime dependence specifier from decl if present
11121111
bool maybeReadLifetimeEntry(SmallVectorImpl<LifetimeEntry> &specifierList,

lib/Serialization/ModuleFormat.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0;
5858
/// describe what change you made. The content of this comment isn't important;
5959
/// it just ensures a conflict if two people change the module format.
6060
/// Don't worry about adhering to the 80-column limit for this line.
61-
const uint16_t SWIFTMODULE_VERSION_MINOR = 941; // add modifier to @_inheritActorContext
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 942; // update LifetimeDependenceLayout
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -2317,6 +2317,7 @@ namespace decls_block {
23172317
using LifetimeDependenceLayout =
23182318
BCRecordLayout<LIFETIME_DEPENDENCE,
23192319
BCVBR<4>, // targetIndex
2320+
BCVBR<4>, // paramIndicesLength
23202321
BCFixed<1>, // isImmortal
23212322
BCFixed<1>, // hasInheritLifetimeParamIndices
23222323
BCFixed<1>, // hasScopeLifetimeParamIndices

lib/Serialization/Serialization.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2738,10 +2738,10 @@ void Serializer::writeLifetimeDependencies(
27382738

27392739
auto abbrCode = DeclTypeAbbrCodes[LifetimeDependenceLayout::Code];
27402740
LifetimeDependenceLayout::emitRecord(
2741-
Out, ScratchRecord, abbrCode, info.getTargetIndex(), info.isImmortal(),
2741+
Out, ScratchRecord, abbrCode, info.getTargetIndex(),
2742+
info.getParamIndicesLength(), info.isImmortal(),
27422743
info.hasInheritLifetimeParamIndices(),
2743-
info.hasScopeLifetimeParamIndices(),
2744-
info.hasAddressableParamIndices(),
2744+
info.hasScopeLifetimeParamIndices(), info.hasAddressableParamIndices(),
27452745
paramIndices);
27462746
paramIndices.clear();
27472747
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module %s -o %t -enable-experimental-feature LifetimeDependence
3+
4+
// RUN: %target-swift-frontend -emit-sil %t/rdar151768216.swiftmodule \
5+
// RUN: -enable-experimental-feature LifetimeDependence
6+
7+
// REQUIRES: swift_feature_LifetimeDependence
8+
9+
// Ensure no crash
10+
extension Result {
11+
@inlinable
12+
func castError(i: Int, j: Int, k: Int) -> Result<Success, Failure> {
13+
return self.mapError { error in
14+
return error
15+
}
16+
}
17+
}
18+

0 commit comments

Comments
 (0)