Skip to content

Commit d0e92f8

Browse files
committed
SIL: Verifier checks resilience invariants for class instructions
1 parent 3f7eb01 commit d0e92f8

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

lib/SIL/SILVerifier.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,8 +2266,14 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
22662266
void checkDeallocRefInst(DeallocRefInst *DI) {
22672267
require(DI->getOperand()->getType().isObject(),
22682268
"Operand of dealloc_ref must be object");
2269-
require(DI->getOperand()->getType().getClassOrBoundGenericClass(),
2270-
"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+
}
22712277
}
22722278
void checkDeallocPartialRefInst(DeallocPartialRefInst *DPRI) {
22732279
require(DPRI->getInstance()->getType().isObject(),
@@ -2281,6 +2287,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
22812287
->getInstanceType()->getClassOrBoundGenericClass();
22822288
require(class2,
22832289
"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");
22842293
while (class1 != class2) {
22852294
class1 = class1->getSuperclassDecl();
22862295
require(class1, "First operand not superclass of second instance type");
@@ -2453,6 +2462,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
24532462
SILType operandTy = EI->getOperand()->getType();
24542463
ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
24552464
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");
24562468

24572469
require(EI->getField()->getDeclContext() == cd,
24582470
"ref_element_addr field must be a member of the class");
@@ -2473,6 +2485,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
24732485
SILType operandTy = RTAI->getOperand()->getType();
24742486
ClassDecl *cd = operandTy.getClassOrBoundGenericClass();
24752487
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");
24762492
}
24772493

24782494
void checkDestructureStructInst(DestructureStructInst *DSI) {

test/IRGen/class_resilience.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import resilient_class
3737
sil @allocResilientOutsideParent : $@convention(thin) () -> () {
3838
bb0:
3939
%c = alloc_ref $ResilientOutsideParent
40-
dealloc_ref %c : $ResilientOutsideParent
40+
strong_release %c : $ResilientOutsideParent
4141
%result = tuple ()
4242
return %result : $()
4343
}

0 commit comments

Comments
 (0)