Skip to content

Commit 03ab389

Browse files
committed
Check if SIL definition referencing a decl is serialized in
a resiliently built module in SIL verifier; this scenario 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 03ab389

File tree

2 files changed

+229
-75
lines changed

2 files changed

+229
-75
lines changed

lib/SIL/Verifier/SILVerifier.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,21 @@ 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,
157+
/// direct access 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 decl D is serialized
163+
// when its defining module M was resiliently built; this means package
164+
// serialization was enabled and direct access to decl D should be
165+
// allowed.
166+
auto serializedInResilientModule = M->isResilient() &&
167+
isSerialized &&
168+
D->getModuleContext()->inSamePackage(M);
169+
return !serializedInResilientModule &&
170+
!D->getModuleContext()->getBypassResilience() &&
162171
D->isResilient(M, expansion);
163172
}
164173

@@ -193,6 +202,7 @@ namespace {
193202
/// Verify invariants on a key path component.
194203
void verifyKeyPathComponent(SILModule &M,
195204
TypeExpansionContext typeExpansionContext,
205+
bool isSerialized,
196206
llvm::function_ref<void(bool, StringRef)> require,
197207
CanType &baseTy,
198208
CanType leafTy,
@@ -300,7 +310,7 @@ void verifyKeyPathComponent(SILModule &M,
300310
"property decl should be a member of the base with the same type "
301311
"as the component");
302312
require(property->hasStorage(), "property must be stored");
303-
require(!checkResilience(property, M.getSwiftModule(), expansion),
313+
require(!checkResilience(property, M.getSwiftModule(), expansion, isSerialized),
304314
"cannot access storage of resilient property");
305315
auto propertyTy =
306316
loweredBaseTy.getFieldType(property, M, typeExpansionContext);
@@ -2469,13 +2479,12 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
24692479
SILGlobalVariable *RefG = AGI->getReferencedGlobal();
24702480
if (auto *VD = RefG->getDecl()) {
24712481
require(!checkResilience(VD, F.getModule().getSwiftModule(),
2472-
F.getResilienceExpansion()),
2482+
F.getResilienceExpansion(), F.isSerialized()),
24732483
"cannot access storage of resilient global");
24742484
}
24752485
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.
24782486
require(RefG->isSerialized()
2487+
// RefG should be visibile if it has package linkage in serialized context.
24792488
|| hasPublicOrPackageVisibility(RefG->getLinkage(), /*includePackage*/ true),
24802489
"alloc_global inside fragile function cannot "
24812490
"reference a private or hidden symbol");
@@ -2490,13 +2499,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
24902499
"global_addr/value must be the type of the variable it references");
24912500
if (auto *VD = RefG->getDecl()) {
24922501
require(!checkResilience(VD, F.getModule().getSwiftModule(),
2493-
F.getResilienceExpansion()),
2502+
F.getResilienceExpansion(), F.isSerialized()),
24942503
"cannot access storage of resilient global");
24952504
}
2505+
24962506
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.
24992507
require(RefG->isSerialized()
2508+
// RefG should be visibile if it has package linkage in serialized context.
25002509
|| hasPublicOrPackageVisibility(RefG->getLinkage(), /*includePackage*/ true),
25012510
"global_addr/value inside fragile function cannot "
25022511
"reference a private or hidden symbol");
@@ -3415,7 +3424,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
34153424
"Cannot build a struct with unreferenceable storage from elements "
34163425
"using StructInst");
34173426
require(!checkResilience(structDecl, F.getModule().getSwiftModule(),
3418-
F.getResilienceExpansion()),
3427+
F.getResilienceExpansion(), F.isSerialized()),
34193428
"cannot access storage of resilient struct");
34203429
require(SI->getType().isObject(),
34213430
"StructInst must produce an object");
@@ -3652,7 +3661,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
36523661
require(cd, "Operand of dealloc_ref must be of class type");
36533662

36543663
require(!checkResilience(cd, F.getModule().getSwiftModule(),
3655-
F.getResilienceExpansion()),
3664+
F.getResilienceExpansion(), F.isSerialized()),
36563665
"cannot directly deallocate resilient class");
36573666
}
36583667
void checkDeallocPartialRefInst(DeallocPartialRefInst *DPRI) {
@@ -3780,7 +3789,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
37803789
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
37813790
require(sd, "must struct_extract from struct");
37823791
require(!checkResilience(sd, F.getModule().getSwiftModule(),
3783-
F.getResilienceExpansion()),
3792+
F.getResilienceExpansion(), F.isSerialized()),
37843793
"cannot access storage of resilient struct");
37853794
require(!EI->getField()->isStatic(),
37863795
"cannot get address of static property with struct_element_addr");
@@ -3836,7 +3845,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
38363845
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
38373846
require(sd, "struct_element_addr operand must be struct address");
38383847
require(!checkResilience(sd, F.getModule().getSwiftModule(),
3839-
F.getResilienceExpansion()),
3848+
F.getResilienceExpansion(), F.isSerialized()),
38403849
"cannot access storage of resilient struct");
38413850
require(EI->getType().isAddress(),
38423851
"result of struct_element_addr must be address");
@@ -3877,8 +3886,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
38773886
SILType operandTy = EI->getOperand()->getType();
38783887
ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
38793888
require(cd, "ref_element_addr operand must be a class instance");
3889+
38803890
require(!checkResilience(cd, F.getModule().getSwiftModule(),
3881-
F.getResilienceExpansion()),
3891+
F.getResilienceExpansion(), F.isSerialized()),
38823892
"cannot access storage of resilient class");
38833893

38843894
require(EI->getField()->getDeclContext() ==
@@ -3904,7 +3914,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
39043914
ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
39053915
require(cd, "ref_tail_addr operand must be a class instance");
39063916
require(!checkResilience(cd, F.getModule().getSwiftModule(),
3907-
F.getResilienceExpansion()),
3917+
F.getResilienceExpansion(), F.isSerialized()),
39083918
"cannot access storage of resilient class");
39093919
require(cd, "ref_tail_addr operand must be a class instance");
39103920
checkAddressWalkerCanVisitAllTransitiveUses(RTAI);
@@ -3915,7 +3925,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
39153925
StructDecl *sd = operandTy.getStructOrBoundGenericStruct();
39163926
require(sd, "must struct_extract from struct");
39173927
require(!checkResilience(sd, F.getModule().getSwiftModule(),
3918-
F.getResilienceExpansion()),
3928+
F.getResilienceExpansion(), F.isSerialized()),
39193929
"cannot access storage of resilient struct");
39203930
if (F.hasOwnership()) {
39213931
// Make sure that all of our destructure results ownership kinds are
@@ -5730,8 +5740,8 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
57305740
hasIndices = false;
57315741
break;
57325742
}
5733-
5734-
verifyKeyPathComponent(F.getModule(), F.getTypeExpansionContext(),
5743+
5744+
verifyKeyPathComponent(F.getModule(), F.getTypeExpansionContext(), F.isSerialized(),
57355745
[&](bool reqt, StringRef message) { _require(reqt, message); },
57365746
baseTy,
57375747
leafTy,
@@ -7205,6 +7215,7 @@ void SILProperty::verify(const SILModule &M) const {
72057215
ResilienceExpansion::Maximal);
72067216
verifyKeyPathComponent(const_cast<SILModule&>(M),
72077217
typeExpansionContext,
7218+
isSerialized(),
72087219
require,
72097220
baseTy,
72107221
leafTy,

0 commit comments

Comments
 (0)