@@ -136,9 +136,8 @@ bool swift::isIntermediateRelease(SILInstruction *I,
136
136
137
137
// This is a release on an owned parameter and its not the epilogue release.
138
138
// Its not the final release.
139
- auto Rel
140
- = EAFI->computeEpilogueARCInstructions (
141
- EpilogueARCContext::EpilogueARCKind::Release, Arg);
139
+ auto Rel = EAFI->computeEpilogueARCInstructions (
140
+ EpilogueARCContext::EpilogueARCKind::Release, Arg);
142
141
if (Rel.size () && !Rel.count (I))
143
142
return true ;
144
143
@@ -1424,9 +1423,22 @@ optimizeBridgedObjCToSwiftCast(SILInstruction *Inst,
1424
1423
assert (Src->getType ().isAddress () && " Source should have an address type" );
1425
1424
assert (Dest->getType ().isAddress () && " Source should have an address type" );
1426
1425
1427
- if (!Src->getType ().isLoadable (M) || !Dest->getType ().isLoadable (M)) {
1428
- // TODO: Handle address only types.
1429
- return nullptr ;
1426
+ // AnyHashable is a special case - it does not conform to NSObject -
1427
+ // If AnyHashable - Bail out of the optimization
1428
+ if (auto DT = Target.getNominalOrBoundGenericNominal ()) {
1429
+ if (DT == M.getASTContext ().getAnyHashableDecl ()) {
1430
+ return nullptr ;
1431
+ }
1432
+ }
1433
+
1434
+ // If this is a conditional cast:
1435
+ // We need a new fail BB in order to add a dealloc_stack to it
1436
+ SILBasicBlock *ConvFailBB = nullptr ;
1437
+ if (isConditional) {
1438
+ auto CurrInsPoint = Builder.getInsertionPoint ();
1439
+ ConvFailBB = splitBasicBlockAndBranch (Builder, &(*FailureBB->begin ()),
1440
+ nullptr , nullptr );
1441
+ Builder.setInsertionPoint (CurrInsPoint);
1430
1442
}
1431
1443
1432
1444
if (SILBridgedTy != Src->getType ()) {
@@ -1435,6 +1447,13 @@ optimizeBridgedObjCToSwiftCast(SILInstruction *Inst,
1435
1447
// - then convert _ObjectiveCBridgeable._ObjectiveCType to
1436
1448
// a Swift type using _forceBridgeFromObjectiveC.
1437
1449
1450
+ if (!Src->getType ().isLoadable (M)) {
1451
+ // This code path is never reached in current test cases
1452
+ // If reached, we'd have to convert from an ObjC Any* to a loadable type
1453
+ // Should use check_addr / make a source we can actually load
1454
+ return nullptr ;
1455
+ }
1456
+
1438
1457
// Generate a load for the source argument.
1439
1458
auto *Load = Builder.createLoad (Loc, Src);
1440
1459
// Try to convert the source into the expected ObjC type first.
@@ -1456,9 +1475,8 @@ optimizeBridgedObjCToSwiftCast(SILInstruction *Inst,
1456
1475
} else if (isConditional) {
1457
1476
SILBasicBlock *CastSuccessBB = Inst->getFunction ()->createBasicBlock ();
1458
1477
CastSuccessBB->createBBArg (SILBridgedTy);
1459
- NewI = Builder.createCheckedCastBranch (Loc, false , Load,
1460
- SILBridgedTy, CastSuccessBB,
1461
- FailureBB);
1478
+ NewI = Builder.createCheckedCastBranch (Loc, false , Load, SILBridgedTy,
1479
+ CastSuccessBB, ConvFailBB);
1462
1480
Builder.setInsertionPoint (CastSuccessBB);
1463
1481
SrcOp = CastSuccessBB->getBBArg (0 );
1464
1482
} else {
@@ -1575,10 +1593,8 @@ optimizeBridgedObjCToSwiftCast(SILInstruction *Inst,
1575
1593
Builder.setInsertionPoint (ConvSuccessBB);
1576
1594
auto Addr = Builder.createUncheckedTakeEnumDataAddr (Loc, InOutOptionalParam,
1577
1595
SomeDecl);
1578
- auto LoadFromOptional = Builder.createLoad (Loc, Addr);
1579
1596
1580
- // Store into Dest
1581
- Builder.createStore (Loc, LoadFromOptional, Dest);
1597
+ Builder.createCopyAddr (Loc, Addr, Dest, IsTake, IsInitialization);
1582
1598
1583
1599
Builder.createDeallocStack (Loc, Tmp);
1584
1600
SmallVector<SILValue, 1 > SuccessBBArgs;
@@ -1607,10 +1623,10 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1607
1623
1608
1624
auto &M = Inst->getModule ();
1609
1625
auto Loc = Inst->getLoc ();
1610
-
1626
+
1627
+ bool AddressOnlyType = false ;
1611
1628
if (!Src->getType ().isLoadable (M) || !Dest->getType ().isLoadable (M)) {
1612
- // TODO: Handle address-only types.
1613
- return nullptr ;
1629
+ AddressOnlyType = true ;
1614
1630
}
1615
1631
1616
1632
// Find the _BridgedToObjectiveC protocol.
@@ -1662,10 +1678,9 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1662
1678
1663
1679
auto SILFnTy = SILType::getPrimitiveObjectType (
1664
1680
M.Types .getConstantFunctionType (BridgeFuncDeclRef));
1665
-
1666
- // TODO: Handle indirect argument to or return from witness function.
1667
- if (ParamTypes[0 ].isIndirect ()
1668
- || BridgedFunc->getLoweredFunctionType ()->getSingleResult ().isIndirect ())
1681
+
1682
+ // TODO: Handle return from witness function.
1683
+ if (BridgedFunc->getLoweredFunctionType ()->getSingleResult ().isIndirect ())
1669
1684
return nullptr ;
1670
1685
1671
1686
// Get substitutions, if source is a bound generic type.
@@ -1677,7 +1692,7 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1677
1692
SILType ResultTy = SubstFnTy.castTo <SILFunctionType>()->getSILResult ();
1678
1693
1679
1694
auto FnRef = Builder.createFunctionRef (Loc, BridgedFunc);
1680
- if (Src->getType ().isAddress ()) {
1695
+ if (Src->getType ().isAddress () && !ParamTypes[ 0 ]. isIndirect () ) {
1681
1696
// Create load
1682
1697
Src = Builder.createLoad (Loc, Src);
1683
1698
}
@@ -1689,6 +1704,8 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1689
1704
bool needReleaseInSucc = false ;
1690
1705
switch (ParamTypes[0 ].getConvention ()) {
1691
1706
case ParameterConvention::Direct_Guaranteed:
1707
+ assert (!AddressOnlyType &&
1708
+ " AddressOnlyType with Direct_Guaranteed is not supported" );
1692
1709
switch (ConsumptionKind) {
1693
1710
case CastConsumptionKind::TakeAlways:
1694
1711
needReleaseAfterCall = true ;
@@ -1718,6 +1735,8 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1718
1735
// The Direct_Owned case is only handled for completeness. Currently this
1719
1736
// cannot appear, because the _bridgeToObjectiveC protocol witness method
1720
1737
// always receives the this pointer (= the source) as guaranteed.
1738
+ assert (!AddressOnlyType &&
1739
+ " AddressOnlyType with Direct_Owned is not supported" );
1721
1740
switch (ConsumptionKind) {
1722
1741
case CastConsumptionKind::TakeAlways:
1723
1742
break ;
@@ -1731,11 +1750,23 @@ optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
1731
1750
}
1732
1751
break ;
1733
1752
case ParameterConvention::Direct_Unowned:
1753
+ assert (!AddressOnlyType &&
1754
+ " AddressOnlyType with Direct_Unowned is not supported" );
1734
1755
break ;
1735
- case ParameterConvention::Indirect_In:
1736
1756
case ParameterConvention::Indirect_In_Guaranteed:
1757
+ // Source as-is, we don't need to copy it due to guarantee
1758
+ break ;
1759
+ case ParameterConvention::Indirect_In: {
1760
+ // Need to make a copy of the source, can be changed in ObjC
1761
+ auto BridgeStack = Builder.createAllocStack (Loc, Src->getType ());
1762
+ Src = Builder.createCopyAddr (Loc, Src, BridgeStack, IsNotTake,
1763
+ IsInitialization);
1764
+ break ;
1765
+ }
1737
1766
case ParameterConvention::Indirect_Inout:
1738
1767
case ParameterConvention::Indirect_InoutAliasable:
1768
+ // TODO handle remaining indirect argument types
1769
+ return nullptr ;
1739
1770
case ParameterConvention::Direct_Deallocating:
1740
1771
llvm_unreachable (" unsupported convention for bridging conversion" );
1741
1772
}
0 commit comments