Skip to content

Commit d1a97f1

Browse files
authored
Merge pull request #81879 from meg-gupta/fixdeserialization
Fix deserialization of lifetime dependencies on ast function types
2 parents b0747b2 + 36f3574 commit d1a97f1

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
@@ -227,6 +227,25 @@ class LifetimeDependenceInfo {
227227
|| !conditionallyAddressableParamIndices
228228
|| conditionallyAddressableParamIndices->isDisjointWith(
229229
addressableParamIndices)));
230+
231+
if (CONDITIONAL_ASSERT_enabled()) {
232+
// Ensure inherit/scope/addressable param indices are of the same length
233+
// or 0.
234+
unsigned paramIndicesLength = 0;
235+
if (inheritLifetimeParamIndices) {
236+
paramIndicesLength = inheritLifetimeParamIndices->getCapacity();
237+
}
238+
if (scopeLifetimeParamIndices) {
239+
assert(paramIndicesLength == 0 ||
240+
paramIndicesLength == scopeLifetimeParamIndices->getCapacity());
241+
paramIndicesLength = scopeLifetimeParamIndices->getCapacity();
242+
}
243+
if (addressableParamIndices) {
244+
assert(paramIndicesLength == 0 ||
245+
paramIndicesLength == addressableParamIndices->getCapacity());
246+
paramIndicesLength = addressableParamIndices->getCapacity();
247+
}
248+
}
230249
}
231250

232251
operator bool() const { return !empty(); }
@@ -250,6 +269,19 @@ class LifetimeDependenceInfo {
250269
return addressableParamIndicesAndImmortal.getPointer() != nullptr;
251270
}
252271

272+
unsigned getParamIndicesLength() const {
273+
if (hasInheritLifetimeParamIndices()) {
274+
return getInheritIndices()->getCapacity();
275+
}
276+
if (hasScopeLifetimeParamIndices()) {
277+
return getScopeIndices()->getCapacity();
278+
}
279+
if (hasAddressableParamIndices()) {
280+
return getAddressableIndices()->getCapacity();
281+
}
282+
return 0;
283+
}
284+
253285
IndexSubset *getInheritIndices() const { return inheritLifetimeParamIndices; }
254286

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

lib/Serialization/Deserialization.cpp

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

38933893
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
3894-
while (auto info = MF.maybeReadLifetimeDependence(bodyParams->size() + 1)) {
3894+
while (auto info = MF.maybeReadLifetimeDependence()) {
38953895
assert(info.has_value());
38963896
lifetimeDependencies.push_back(*info);
38973897
}
@@ -4493,11 +4493,9 @@ class DeclDeserializer {
44934493
ParameterList *paramList;
44944494
SET_OR_RETURN_ERROR(paramList, MF.readParameterList());
44954495
fn->setParameters(paramList);
4496-
auto numParams =
4497-
fn->hasImplicitSelfDecl() ? paramList->size() + 1 : paramList->size();
44984496

44994497
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
4500-
while (auto info = MF.maybeReadLifetimeDependence(numParams)) {
4498+
while (auto info = MF.maybeReadLifetimeDependence()) {
45014499
assert(info.has_value());
45024500
lifetimeDependencies.push_back(*info);
45034501
}
@@ -7438,8 +7436,7 @@ detail::function_deserializer::deserialize(ModuleFile &MF,
74387436

74397437
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
74407438

7441-
while (auto lifetimeDependence =
7442-
MF.maybeReadLifetimeDependence(params.size())) {
7439+
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence()) {
74437440
lifetimeDependencies.push_back(*lifetimeDependence);
74447441
}
74457442
if (!lifetimeDependencies.empty()) {
@@ -8091,7 +8088,7 @@ Expected<Type> DESERIALIZE_TYPE(SIL_FUNCTION_TYPE)(
80918088

80928089
SmallVector<LifetimeDependenceInfo, 1> lifetimeDependencies;
80938090

8094-
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence(numParams)) {
8091+
while (auto lifetimeDependence = MF.maybeReadLifetimeDependence()) {
80958092
lifetimeDependencies.push_back(*lifetimeDependence);
80968093
}
80978094

@@ -9378,7 +9375,7 @@ bool ModuleFile::maybeReadLifetimeDependenceRecord(
93789375
}
93799376

93809377
std::optional<LifetimeDependenceInfo>
9381-
ModuleFile::maybeReadLifetimeDependence(unsigned numParams) {
9378+
ModuleFile::maybeReadLifetimeDependence() {
93829379
using namespace decls_block;
93839380

93849381
SmallVector<uint64_t, 8> scratch;
@@ -9387,28 +9384,29 @@ ModuleFile::maybeReadLifetimeDependence(unsigned numParams) {
93879384
}
93889385

93899386
unsigned targetIndex;
9387+
unsigned paramIndicesLength;
93909388
bool isImmortal;
93919389
bool hasInheritLifetimeParamIndices;
93929390
bool hasScopeLifetimeParamIndices;
93939391
bool hasAddressableParamIndices;
93949392
ArrayRef<uint64_t> lifetimeDependenceData;
93959393
LifetimeDependenceLayout::readRecord(
9396-
scratch, targetIndex, isImmortal, hasInheritLifetimeParamIndices,
9397-
hasScopeLifetimeParamIndices, hasAddressableParamIndices,
9398-
lifetimeDependenceData);
9394+
scratch, targetIndex, paramIndicesLength, isImmortal,
9395+
hasInheritLifetimeParamIndices, hasScopeLifetimeParamIndices,
9396+
hasAddressableParamIndices, lifetimeDependenceData);
93999397

9400-
SmallBitVector inheritLifetimeParamIndices(numParams, false);
9401-
SmallBitVector scopeLifetimeParamIndices(numParams, false);
9402-
SmallBitVector addressableParamIndices(numParams, false);
9398+
SmallBitVector inheritLifetimeParamIndices(paramIndicesLength, false);
9399+
SmallBitVector scopeLifetimeParamIndices(paramIndicesLength, false);
9400+
SmallBitVector addressableParamIndices(paramIndicesLength, false);
94039401

94049402
unsigned startIndex = 0;
94059403
auto pushData = [&](SmallBitVector &bits) {
9406-
for (unsigned i = 0; i < numParams; i++) {
9404+
for (unsigned i = 0; i < paramIndicesLength; i++) {
94079405
if (lifetimeDependenceData[startIndex + i]) {
94089406
bits.set(i);
94099407
}
94109408
}
9411-
startIndex += numParams;
9409+
startIndex += paramIndicesLength;
94129410
};
94139411

94149412
if (hasInheritLifetimeParamIndices) {

lib/Serialization/ModuleFile.h

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

11021102
// Reads lifetime dependence info from type if present.
1103-
std::optional<LifetimeDependenceInfo>
1104-
maybeReadLifetimeDependence(unsigned numParams);
1103+
std::optional<LifetimeDependenceInfo> maybeReadLifetimeDependence();
11051104

11061105
// Reads lifetime dependence specifier from decl if present
11071106
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 = 952; // Add @specialized
61+
const uint16_t SWIFTMODULE_VERSION_MINOR = 953; // update LifetimeDependence layout
6262

6363
/// A standard hash seed used for all string hashes in a serialized module.
6464
///
@@ -2323,6 +2323,7 @@ namespace decls_block {
23232323
using LifetimeDependenceLayout =
23242324
BCRecordLayout<LIFETIME_DEPENDENCE,
23252325
BCVBR<4>, // targetIndex
2326+
BCVBR<4>, // paramIndicesLength
23262327
BCFixed<1>, // isImmortal
23272328
BCFixed<1>, // hasInheritLifetimeParamIndices
23282329
BCFixed<1>, // hasScopeLifetimeParamIndices

lib/Serialization/Serialization.cpp

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

27352735
auto abbrCode = DeclTypeAbbrCodes[LifetimeDependenceLayout::Code];
27362736
LifetimeDependenceLayout::emitRecord(
2737-
Out, ScratchRecord, abbrCode, info.getTargetIndex(), info.isImmortal(),
2737+
Out, ScratchRecord, abbrCode, info.getTargetIndex(),
2738+
info.getParamIndicesLength(), info.isImmortal(),
27382739
info.hasInheritLifetimeParamIndices(),
2739-
info.hasScopeLifetimeParamIndices(),
2740-
info.hasAddressableParamIndices(),
2740+
info.hasScopeLifetimeParamIndices(), info.hasAddressableParamIndices(),
27412741
paramIndices);
27422742
paramIndices.clear();
27432743
}
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)