Skip to content

Commit 2126401

Browse files
committed
CastOptimizer: fix optimization of casts from non-existentials to existentials
We need to consider that archetypes (generic types) can be existentials if they conform to self-conforming protocols. Fixes a miscompile rdar://147269904
1 parent 1b5f9f9 commit 2126401

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

lib/SILOptimizer/Utils/CastOptimizer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1450,7 +1450,7 @@ static bool optimizeStaticallyKnownProtocolConformance(
14501450
auto &Mod = Inst->getModule();
14511451

14521452
if (TargetType->isAnyExistentialType() &&
1453-
!SourceType->isAnyExistentialType()) {
1453+
!SourceType->canBeExistential()) {
14541454
auto &Ctx = Mod.getASTContext();
14551455

14561456
auto *Proto = dyn_cast_or_null<ProtocolDecl>(TargetType->getAnyNominal());

test/SILOptimizer/constant_propagation.sil

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,6 +1425,33 @@ bb0(%0 : $*Error, %1 : $*E1):
14251425
return %2 : $()
14261426
}
14271427

1428+
// CHECK-LABEL: sil [ossa] @generic_to_existential_cast
1429+
// CHECK: init_existential_addr
1430+
// CHECK: } // end sil function 'generic_to_existential_cast'
1431+
sil [ossa] @generic_to_existential_cast : $@convention(thin) <T where T : P> (@in_guaranteed T) -> @out any P {
1432+
bb0(%0: $*any P, %1 : $*T):
1433+
%29 = alloc_stack $T
1434+
copy_addr %1 to [init] %29
1435+
unconditional_checked_cast_addr T in %29 to any P in %0
1436+
dealloc_stack %29
1437+
%10 = tuple ()
1438+
return %10
1439+
}
1440+
1441+
// CHECK-LABEL: sil [ossa] @existential_generic_to_existential_cast
1442+
// CHECK: unconditional_checked_cast_addr
1443+
// CHECK: } // end sil function 'existential_generic_to_existential_cast'
1444+
sil [ossa] @existential_generic_to_existential_cast : $@convention(thin) <T where T : Error> (@in_guaranteed T) -> @owned any Error {
1445+
bb0(%0 : $*T):
1446+
%29 = alloc_stack $T
1447+
copy_addr %0 to [init] %29
1448+
%31 = alloc_stack $any Error
1449+
unconditional_checked_cast_addr T in %29 to any Error in %31
1450+
%33 = load [take] %31
1451+
dealloc_stack %31
1452+
dealloc_stack %29
1453+
return %33
1454+
}
14281455
// Test constant folding of Builtin.globalStringTablePointer.
14291456

14301457
// CHECK-LABEL: sil @replace_global_string_table_pointer

0 commit comments

Comments
 (0)