Skip to content

Commit b51b1fa

Browse files
committed
Check if SIL function definition referencing a decl is serialized in
minimal ResilienceExpansion in SIL verifier; this can happen if package serialization is enabled and a direct access to the decl should be allowed in such case. rdar://126157356
1 parent 4b440a1 commit b51b1fa

File tree

2 files changed

+228
-75
lines changed

2 files changed

+228
-75
lines changed

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,20 @@ static bool isArchetypeValidInFunction(ArchetypeType *A, const SILFunction *F) {
153153

154154
namespace {
155155

156-
/// When resilience is bypassed, direct access is legal, but the decls are still
157-
/// resilient.
156+
/// When resilience is bypassed or package serialization is enabled, direct access
157+
/// is legal, but the decls are still resilient.
158158
template <typename DeclType>
159159
bool checkResilience(DeclType *D, ModuleDecl *M,
160-
ResilienceExpansion expansion) {
161-
return !D->getModuleContext()->getBypassResilience() &&
160+
ResilienceExpansion expansion,
161+
bool isSerialized) {
162+
// Check whether the SIL definition referencing D is serialized but
163+
// in minimal resilience expansion context (e.g. M was resiliently
164+
// built); this means package serialization was enabled and direct
165+
// access should be allowed.
166+
auto serializedInResilientMode =
167+
expansion == ResilienceExpansion::Minimal && isSerialized;
168+
return !serializedInResilientMode &&
169+
!D->getModuleContext()->getBypassResilience() &&
162170
D->isResilient(M, expansion);
163171
}
164172

@@ -193,6 +201,7 @@ namespace {
193201
/// Verify invariants on a key path component.
194202
void verifyKeyPathComponent(SILModule &M,
195203
TypeExpansionContext typeExpansionContext,
204+
bool isSerialized,
196205
llvm::function_ref<void(bool, StringRef)> require,
197206
CanType &baseTy,
198207
CanType leafTy,
@@ -300,7 +309,7 @@ void verifyKeyPathComponent(SILModule &M,
300309
"property decl should be a member of the base with the same type "
301310
"as the component");
302311
require(property->hasStorage(), "property must be stored");
303-
require(!checkResilience(property, M.getSwiftModule(), expansion),
312+
require(!checkResilience(property, M.getSwiftModule(), expansion, isSerialized),
304313
"cannot access storage of resilient property");
305314
auto propertyTy =
306315
loweredBaseTy.getFieldType(property, M, typeExpansionContext);
@@ -2469,13 +2478,12 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
24692478
SILGlobalVariable *RefG = AGI->getReferencedGlobal();
24702479
if (auto *VD = RefG->getDecl()) {
24712480
require(!checkResilience(VD, F.getModule().getSwiftModule(),
2472-
F.getResilienceExpansion()),
2481+
F.getResilienceExpansion(), F.isSerialized()),
24732482
"cannot access storage of resilient global");
24742483
}
24752484
if (F.isSerialized()) {
2476-
// If it has a package linkage at this point, package CMO must
2477-
// have been enabled, so opt in for visibility.
24782485
require(RefG->isSerialized()
2486+
// RefG should be visibile if it has package linkage in serialized context.
24792487
|| hasPublicOrPackageVisibility(RefG->getLinkage(), /*includePackage*/ true),
24802488
"alloc_global inside fragile function cannot "
24812489
"reference a private or hidden symbol");
@@ -2490,13 +2498,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
24902498
"global_addr/value must be the type of the variable it references");
24912499
if (auto *VD = RefG->getDecl()) {
24922500
require(!checkResilience(VD, F.getModule().getSwiftModule(),
2493-
F.getResilienceExpansion()),
2501+
F.getResilienceExpansion(), F.isSerialized()),
24942502
"cannot access storage of resilient global");
24952503
}
2504+
24962505
if (F.isSerialized()) {
2497-
// If it has a package linkage at this point, package CMO must
2498-
// have been enabled, so opt in for visibility.
24992506
require(RefG->isSerialized()
2507+
// RefG should be visibile if it has package linkage in serialized context.
25002508
|| hasPublicOrPackageVisibility(RefG->getLinkage(), /*includePackage*/ true),
25012509
"global_addr/value inside fragile function cannot "
25022510
"reference a private or hidden symbol");
@@ -3415,7 +3423,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
34153423
"Cannot build a struct with unreferenceable storage from elements "
34163424
"using StructInst");
34173425
require(!checkResilience(structDecl, F.getModule().getSwiftModule(),
3418-
F.getResilienceExpansion()),
3426+
F.getResilienceExpansion(), F.isSerialized()),
34193427
"cannot access storage of resilient struct");
34203428
require(SI->getType().isObject(),
34213429
"StructInst must produce an object");
@@ -3652,7 +3660,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
36523660
require(cd, "Operand of dealloc_ref must be of class type");
36533661

36543662
require(!checkResilience(cd, F.getModule().getSwiftModule(),
3655-
F.getResilienceExpansion()),
3663+
F.getResilienceExpansion(), F.isSerialized()),
36563664
"cannot directly deallocate resilient class");
36573665
}
36583666
void checkDeallocPartialRefInst(DeallocPartialRefInst *DPRI) {
@@ -3780,7 +3788,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
37803788
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
37813789
require(sd, "must struct_extract from struct");
37823790
require(!checkResilience(sd, F.getModule().getSwiftModule(),
3783-
F.getResilienceExpansion()),
3791+
F.getResilienceExpansion(), F.isSerialized()),
37843792
"cannot access storage of resilient struct");
37853793
require(!EI->getField()->isStatic(),
37863794
"cannot get address of static property with struct_element_addr");
@@ -3836,7 +3844,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
38363844
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
38373845
require(sd, "struct_element_addr operand must be struct address");
38383846
require(!checkResilience(sd, F.getModule().getSwiftModule(),
3839-
F.getResilienceExpansion()),
3847+
F.getResilienceExpansion(), F.isSerialized()),
38403848
"cannot access storage of resilient struct");
38413849
require(EI->getType().isAddress(),
38423850
"result of struct_element_addr must be address");
@@ -3877,8 +3885,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
38773885
SILType operandTy = EI->getOperand()->getType();
38783886
ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
38793887
require(cd, "ref_element_addr operand must be a class instance");
3888+
38803889
require(!checkResilience(cd, F.getModule().getSwiftModule(),
3881-
F.getResilienceExpansion()),
3890+
F.getResilienceExpansion(), F.isSerialized()),
38823891
"cannot access storage of resilient class");
38833892

38843893
require(EI->getField()->getDeclContext() ==
@@ -3904,7 +3913,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
39043913
ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
39053914
require(cd, "ref_tail_addr operand must be a class instance");
39063915
require(!checkResilience(cd, F.getModule().getSwiftModule(),
3907-
F.getResilienceExpansion()),
3916+
F.getResilienceExpansion(), F.isSerialized()),
39083917
"cannot access storage of resilient class");
39093918
require(cd, "ref_tail_addr operand must be a class instance");
39103919
checkAddressWalkerCanVisitAllTransitiveUses(RTAI);
@@ -3915,7 +3924,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
39153924
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
39163925
require(sd, "must struct_extract from struct");
39173926
require(!checkResilience(sd, F.getModule().getSwiftModule(),
3918-
F.getResilienceExpansion()),
3927+
F.getResilienceExpansion(), F.isSerialized()),
39193928
"cannot access storage of resilient struct");
39203929
if (F.hasOwnership()) {
39213930
// Make sure that all of our destructure results ownership kinds are
@@ -5730,8 +5739,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
57305739
hasIndices = false;
57315740
break;
57325741
}
5733-
5734-
verifyKeyPathComponent(F.getModule(), F.getTypeExpansionContext(),
5742+
5743+
verifyKeyPathComponent(F.getModule(), F.getTypeExpansionContext(), F.isSerialized(),
57355744
[&](bool reqt, StringRef message) { _require(reqt, message); },
57365745
baseTy,
57375746
leafTy,
@@ -7205,6 +7214,7 @@ void SILProperty::verify(const SILModule &M) const {
72057214
ResilienceExpansion::Maximal);
72067215
verifyKeyPathComponent(const_cast<SILModule&>(M),
72077216
typeExpansionContext,
7217+
isSerialized(),
72087218
require,
72097219
baseTy,
72107220
leafTy,

0 commit comments

Comments
 (0)