Skip to content

Commit 4e9f737

Browse files
committed
[Bridging cast optimization] Unchecked casts can perform a class downcast.
Handle a class downcast following a bridging cast. Fixes rdar://problem/31791421.
1 parent ebcb438 commit 4e9f737

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

lib/SILOptimizer/Utils/Local.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,9 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
16611661
if ((ConvTy == DestTy || DestTy.isExactSuperclassOf(ConvTy))) {
16621662
CastedValue = SILValue(
16631663
(ConvTy == DestTy) ? NewI : Builder.createUpcast(Loc, NewAI, DestTy));
1664+
} else if (ConvTy.isExactSuperclassOf(DestTy)) {
1665+
CastedValue = SILValue(
1666+
Builder.createUnconditionalCheckedCast(Loc, NewAI, DestTy));
16641667
} else if (ConvTy.getSwiftRValueType() ==
16651668
getNSBridgedClassOfCFClass(M.getSwiftModule(),
16661669
DestTy.getSwiftRValueType()) ||
@@ -1673,8 +1676,7 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
16731676
} else {
16741677
llvm_unreachable(
16751678
"Destination should have the same type, be bridgeable CF "
1676-
"type or be a superclass "
1677-
"of the source operand");
1679+
"type or be a superclass/subclass of the source operand");
16781680
}
16791681
NewI = Builder.createStore(Loc, CastedValue, Dest,
16801682
StoreOwnershipQualifier::Unqualified);

test/SILOptimizer/bridged_casts_folding.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,4 +900,16 @@ public func testCondCastSwiftToCFSetInt() -> CFSet? {
900900
return setOpt
901901
}
902902

903+
public class NSObjectSubclass : NSObject { }
903904

905+
var anyHashable: AnyHashable = 0
906+
907+
// CHECK-LABEL: _T021bridged_casts_folding29testUncondCastSwiftToSubclassAA08NSObjectI0CyF
908+
// CHECK: [[GLOBAL:%[0-9]+]] = global_addr @_T021bridged_casts_folding11anyHashables03AnyE0Vv
909+
// CHECK: function_ref @_T0s11AnyHashableV10FoundationE19_bridgeToObjectiveCSo8NSObjectCyF
910+
// CHECK-NEXT: apply
911+
// CHECK-NEXT: unconditional_checked_cast {{%.*}} : $NSObject to $NSObjectSubclass
912+
@inline(never)
913+
public func testUncondCastSwiftToSubclass() -> NSObjectSubclass {
914+
return anyHashable as! NSObjectSubclass
915+
}

0 commit comments

Comments
 (0)