@@ -119,6 +119,7 @@ namespace {
119
119
120
120
// / Verify invariants on a key path component.
121
121
void verifyKeyPathComponent (SILModule &M,
122
+ ResilienceExpansion expansion,
122
123
llvm::function_ref<void (bool , StringRef)> require,
123
124
CanType &baseTy,
124
125
CanType leafTy,
@@ -211,13 +212,21 @@ void verifyKeyPathComponent(SILModule &M,
211
212
switch (auto kind = component.getKind ()) {
212
213
case KeyPathPatternComponent::Kind::StoredProperty: {
213
214
auto property = component.getStoredPropertyDecl ();
215
+ if (expansion == ResilienceExpansion::Minimal) {
216
+ require (property->getEffectiveAccess () >= AccessLevel::Public,
217
+ " Key path in serialized function cannot reference non-public "
218
+ " property" );
219
+ }
220
+
214
221
auto fieldTy = baseTy->getTypeOfMember (M.getSwiftModule (), property)
215
222
->getReferenceStorageReferent ()
216
223
->getCanonicalType ();
217
224
require (fieldTy == componentTy,
218
225
" property decl should be a member of the base with the same type "
219
226
" as the component" );
220
227
require (property->hasStorage (), " property must be stored" );
228
+ require (!property->isResilient (M.getSwiftModule (), expansion),
229
+ " cannot access storage of resilient property" );
221
230
auto propertyTy = loweredBaseTy.getFieldType (property, M);
222
231
require (propertyTy.getObjectType ()
223
232
== loweredComponentTy.getObjectType (),
@@ -247,6 +256,12 @@ void verifyKeyPathComponent(SILModule &M,
247
256
// Getter should be <Sig...> @convention(thin) (@in_guaranteed Base) -> @out Result
248
257
{
249
258
auto getter = component.getComputedPropertyGetter ();
259
+ if (expansion == ResilienceExpansion::Minimal) {
260
+ require (getter->hasValidLinkageForFragileRef (),
261
+ " Key path in serialized function should not reference "
262
+ " less visible getters" );
263
+ }
264
+
250
265
auto substGetterType = getter->getLoweredFunctionType ()
251
266
->substGenericArgs (M, patternSubs);
252
267
require (substGetterType->getRepresentation () ==
@@ -286,6 +301,12 @@ void verifyKeyPathComponent(SILModule &M,
286
301
// <Sig...> @convention(thin) (@in_guaranteed Result, @in Base) -> ()
287
302
288
303
auto setter = component.getComputedPropertySetter ();
304
+ if (expansion == ResilienceExpansion::Minimal) {
305
+ require (setter->hasValidLinkageForFragileRef (),
306
+ " Key path in serialized function should not reference "
307
+ " less visible setters" );
308
+ }
309
+
289
310
auto substSetterType = setter->getLoweredFunctionType ()
290
311
->substGenericArgs (M, patternSubs);
291
312
@@ -1456,8 +1477,13 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
1456
1477
}
1457
1478
1458
1479
void checkAllocGlobalInst (AllocGlobalInst *AGI) {
1480
+ SILGlobalVariable *RefG = AGI->getReferencedGlobal ();
1481
+ if (auto *VD = RefG->getDecl ()) {
1482
+ require (!VD->isResilient (F.getModule ().getSwiftModule (),
1483
+ F.getResilienceExpansion ()),
1484
+ " cannot access storage of resilient global" );
1485
+ }
1459
1486
if (F.isSerialized ()) {
1460
- SILGlobalVariable *RefG = AGI->getReferencedGlobal ();
1461
1487
require (RefG->isSerialized ()
1462
1488
|| hasPublicVisibility (RefG->getLinkage ()),
1463
1489
" alloc_global inside fragile function cannot "
@@ -1469,6 +1495,11 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
1469
1495
SILGlobalVariable *RefG = GAI->getReferencedGlobal ();
1470
1496
require (GAI->getType ().getObjectType () == RefG->getLoweredType (),
1471
1497
" global_addr/value must be the type of the variable it references" );
1498
+ if (auto *VD = RefG->getDecl ()) {
1499
+ require (!VD->isResilient (F.getModule ().getSwiftModule (),
1500
+ F.getResilienceExpansion ()),
1501
+ " cannot access storage of resilient global" );
1502
+ }
1472
1503
if (F.isSerialized ()) {
1473
1504
require (RefG->isSerialized ()
1474
1505
|| hasPublicVisibility (RefG->getLinkage ()),
@@ -2041,6 +2072,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2041
2072
require (!structDecl->hasUnreferenceableStorage (),
2042
2073
" Cannot build a struct with unreferenceable storage from elements "
2043
2074
" using StructInst" );
2075
+ require (!structDecl->isResilient (F.getModule ().getSwiftModule (),
2076
+ F.getResilienceExpansion ()),
2077
+ " cannot access storage of resilient struct" );
2044
2078
require (SI->getType ().isObject (),
2045
2079
" StructInst must produce an object" );
2046
2080
@@ -2232,8 +2266,14 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2232
2266
void checkDeallocRefInst (DeallocRefInst *DI) {
2233
2267
require (DI->getOperand ()->getType ().isObject (),
2234
2268
" Operand of dealloc_ref must be object" );
2235
- require (DI->getOperand ()->getType ().getClassOrBoundGenericClass (),
2236
- " Operand of dealloc_ref must be of class type" );
2269
+ auto *cd = DI->getOperand ()->getType ().getClassOrBoundGenericClass ();
2270
+ require (cd, " Operand of dealloc_ref must be of class type" );
2271
+
2272
+ if (!DI->canAllocOnStack ()) {
2273
+ require (!cd->isResilient (F.getModule ().getSwiftModule (),
2274
+ F.getResilienceExpansion ()),
2275
+ " cannot directly deallocate resilient class" );
2276
+ }
2237
2277
}
2238
2278
void checkDeallocPartialRefInst (DeallocPartialRefInst *DPRI) {
2239
2279
require (DPRI->getInstance ()->getType ().isObject (),
@@ -2247,6 +2287,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2247
2287
->getInstanceType ()->getClassOrBoundGenericClass ();
2248
2288
require (class2,
2249
2289
" Second operand of dealloc_partial_ref must be a class metatype" );
2290
+ require (!class2->isResilient (F.getModule ().getSwiftModule (),
2291
+ F.getResilienceExpansion ()),
2292
+ " cannot directly deallocate resilient class" );
2250
2293
while (class1 != class2) {
2251
2294
class1 = class1->getSuperclassDecl ();
2252
2295
require (class1, " First operand not superclass of second instance type" );
@@ -2343,6 +2386,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2343
2386
" result of struct_extract cannot be address" );
2344
2387
StructDecl *sd = operandTy.getStructOrBoundGenericStruct ();
2345
2388
require (sd, " must struct_extract from struct" );
2389
+ require (!sd->isResilient (F.getModule ().getSwiftModule (),
2390
+ F.getResilienceExpansion ()),
2391
+ " cannot access storage of resilient struct" );
2346
2392
require (!EI->getField ()->isStatic (),
2347
2393
" cannot get address of static property with struct_element_addr" );
2348
2394
require (EI->getField ()->hasStorage (),
@@ -2384,6 +2430,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2384
2430
" must derive struct_element_addr from address" );
2385
2431
StructDecl *sd = operandTy.getStructOrBoundGenericStruct ();
2386
2432
require (sd, " struct_element_addr operand must be struct address" );
2433
+ require (!sd->isResilient (F.getModule ().getSwiftModule (),
2434
+ F.getResilienceExpansion ()),
2435
+ " cannot access storage of resilient struct" );
2387
2436
require (EI->getType ().isAddress (),
2388
2437
" result of struct_element_addr must be address" );
2389
2438
require (!EI->getField ()->isStatic (),
@@ -2413,6 +2462,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2413
2462
SILType operandTy = EI->getOperand ()->getType ();
2414
2463
ClassDecl *cd = operandTy.getClassOrBoundGenericClass ();
2415
2464
require (cd, " ref_element_addr operand must be a class instance" );
2465
+ require (!cd->isResilient (F.getModule ().getSwiftModule (),
2466
+ F.getResilienceExpansion ()),
2467
+ " cannot access storage of resilient class" );
2416
2468
2417
2469
require (EI->getField ()->getDeclContext () == cd,
2418
2470
" ref_element_addr field must be a member of the class" );
@@ -2433,8 +2485,21 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
2433
2485
SILType operandTy = RTAI->getOperand ()->getType ();
2434
2486
ClassDecl *cd = operandTy.getClassOrBoundGenericClass ();
2435
2487
require (cd, " ref_tail_addr operand must be a class instance" );
2488
+ require (!cd->isResilient (F.getModule ().getSwiftModule (),
2489
+ F.getResilienceExpansion ()),
2490
+ " cannot access storage of resilient class" );
2491
+ require (cd, " ref_tail_addr operand must be a class instance" );
2436
2492
}
2437
-
2493
+
2494
+ void checkDestructureStructInst (DestructureStructInst *DSI) {
2495
+ SILType operandTy = DSI->getOperand ()->getType ();
2496
+ StructDecl *sd = operandTy.getStructOrBoundGenericStruct ();
2497
+ require (sd, " must struct_extract from struct" );
2498
+ require (!sd->isResilient (F.getModule ().getSwiftModule (),
2499
+ F.getResilienceExpansion ()),
2500
+ " cannot access storage of resilient struct" );
2501
+ }
2502
+
2438
2503
SILType getMethodSelfType (CanSILFunctionType ft) {
2439
2504
return fnConv.getSILType (ft->getParameters ().back ());
2440
2505
}
@@ -3867,8 +3932,6 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
3867
3932
3868
3933
// Find the set of enum elements for the type so we can verify
3869
3934
// exhaustiveness.
3870
- // FIXME: We also need to consider if the enum is resilient, in which case
3871
- // we're never guaranteed to be exhaustive.
3872
3935
llvm::DenseSet<EnumElementDecl*> unswitchedElts;
3873
3936
uDecl->getAllElements (unswitchedElts);
3874
3937
@@ -3954,8 +4017,6 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
3954
4017
3955
4018
// Find the set of enum elements for the type so we can verify
3956
4019
// exhaustiveness.
3957
- // FIXME: We also need to consider if the enum is resilient, in which case
3958
- // we're never guaranteed to be exhaustive.
3959
4020
llvm::DenseSet<EnumElementDecl*> unswitchedElts;
3960
4021
uDecl->getAllElements (unswitchedElts);
3961
4022
@@ -3979,9 +4040,12 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
3979
4040
}
3980
4041
3981
4042
// If the switch is non-exhaustive, we require a default.
3982
- require (unswitchedElts.empty () || SOI->hasDefault (),
3983
- " nonexhaustive switch_enum_addr must have a default "
3984
- " destination" );
4043
+ bool isExhaustive =
4044
+ uDecl->isEffectivelyExhaustive (F.getModule ().getSwiftModule (),
4045
+ F.getResilienceExpansion ());
4046
+ require ((isExhaustive && unswitchedElts.empty ()) || SOI->hasDefault (),
4047
+ " nonexhaustive switch_enum_addr must have a default destination" );
4048
+
3985
4049
if (SOI->hasDefault ())
3986
4050
require (SOI->getDefaultBB ()->args_empty (),
3987
4051
" switch_enum_addr default destination must take "
@@ -4242,7 +4306,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
4242
4306
break ;
4243
4307
}
4244
4308
4245
- verifyKeyPathComponent (F.getModule (),
4309
+ verifyKeyPathComponent (F.getModule (), F. getResilienceExpansion (),
4246
4310
[&](bool reqt, StringRef message) { _require (reqt, message); },
4247
4311
baseTy,
4248
4312
leafTy,
@@ -4879,15 +4943,16 @@ void SILProperty::verify(const SILModule &M) const {
4879
4943
4880
4944
if (auto &component = getComponent ()) {
4881
4945
verifyKeyPathComponent (const_cast <SILModule&>(M),
4882
- require,
4883
- baseTy,
4884
- leafTy,
4885
- *component,
4886
- {},
4887
- canSig,
4888
- subs,
4889
- /* property descriptor*/ true ,
4890
- hasIndices);
4946
+ ResilienceExpansion::Maximal,
4947
+ require,
4948
+ baseTy,
4949
+ leafTy,
4950
+ *component,
4951
+ {},
4952
+ canSig,
4953
+ subs,
4954
+ /* property descriptor*/ true ,
4955
+ hasIndices);
4891
4956
// verifyKeyPathComponent updates baseTy to be the projected type of the
4892
4957
// component, which should be the same as the type of the declared storage
4893
4958
require (baseTy == leafTy,
0 commit comments