Skip to content

Commit e178348

Browse files
committed
SILCombine: fix an assertion crash in SILCombine when casting AnyClass to Any
This caused a problem when propagating the concrete type of an existential: if the concrete type is itself an opened existential, it was not added to the OpenedArchetypeTracker. https://bugs.swift.org/browse/SR-13444 rdar://problem/68077098
1 parent f9c6f3a commit e178348

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,8 @@ void SILCombiner::buildConcreteOpenedExistentialInfos(
584584
// BuilderContext before rewriting any uses of the ConcreteType.
585585
OpenedArchetypesTracker.addOpenedArchetypeDef(
586586
cast<ArchetypeType>(CEI.ConcreteType), CEI.ConcreteTypeDef);
587+
} else if (auto *I = CEI.ConcreteValue->getDefiningInstruction()) {
588+
OpenedArchetypesTracker.registerUsedOpenedArchetypes(I);
587589
}
588590
}
589591
}

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,8 @@ SILInstruction *SILCombiner::visitAllocStackInst(AllocStackInst *AS) {
480480
// Be careful with open archetypes, because they cannot be moved before
481481
// their definitions.
482482
if (IEI && !OEI &&
483-
!IEI->getLoweredConcreteType().isOpenedExistential()) {
483+
!IEI->getLoweredConcreteType().hasOpenedExistential()) {
484+
assert(!IEI->getLoweredConcreteType().isOpenedExistential());
484485
auto *ConcAlloc = Builder.createAllocStack(
485486
AS->getLoc(), IEI->getLoweredConcreteType(), AS->getVarInfo());
486487
IEI->replaceAllUsesWith(ConcAlloc);

test/SILOptimizer/sil_combine.sil

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3189,6 +3189,33 @@ bb0(%0 : $VV):
31893189
return %26 : $()
31903190
}
31913191

3192+
sil @any_to_object : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned AnyObject
3193+
3194+
// CHECK-LABEL: sil @dont_crash_when_propagating_existentials
3195+
// CHECK: [[EM:%[0-9]+]] = init_existential_metatype %0
3196+
// CHECK: [[S:%[0-9]+]] = alloc_stack $Any
3197+
// CHECK: [[M:%[0-9]+]] = open_existential_metatype [[EM]]
3198+
// CHECK: [[E:%[0-9]+]] = init_existential_addr [[S]]
3199+
// CHECK: store [[M]] to [[E]]
3200+
// CHECK: apply {{%[0-9]+}}<(@opened("5F99B72C-EC40-11EA-9534-8C8590A6A134") AnyObject).Type>([[E]])
3201+
// CHECK: } // end sil function 'dont_crash_when_propagating_existentials'
3202+
sil @dont_crash_when_propagating_existentials : $@convention(thin) () -> @owned AnyObject {
3203+
bb0:
3204+
%0 = metatype $@thick C.Type
3205+
%1 = init_existential_metatype %0 : $@thick C.Type, $@thick AnyObject.Type
3206+
%3 = alloc_stack $Any, let, name "object"
3207+
%4 = open_existential_metatype %1 : $@thick AnyObject.Type to $@thick (@opened("5F99B72C-EC40-11EA-9534-8C8590A6A134") AnyObject).Type
3208+
%5 = init_existential_addr %3 : $*Any, $(@opened("5F99B72C-EC40-11EA-9534-8C8590A6A134") AnyObject).Type
3209+
store %4 to %5 : $*@thick (@opened("5F99B72C-EC40-11EA-9534-8C8590A6A134") AnyObject).Type
3210+
%7 = open_existential_addr immutable_access %3 : $*Any to $*@opened("5F9F1B04-EC40-11EA-9534-8C8590A6A134") Any
3211+
%8 = function_ref @any_to_object : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned AnyObject
3212+
%9 = apply %8<@opened("5F9F1B04-EC40-11EA-9534-8C8590A6A134") Any>(%7) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @owned AnyObject
3213+
destroy_addr %3 : $*Any
3214+
dealloc_stack %3 : $*Any
3215+
return %9 : $AnyObject
3216+
}
3217+
3218+
31923219
// CHECK-LABEL: sil @remove_unused_alloc_ref
31933220
// CHECK-NEXT: bb0
31943221
// CHECK-NEXT: %0 = tuple ()

0 commit comments

Comments
 (0)