@@ -194,18 +194,49 @@ struct UseDefChainVisitor
194194} // namespace
195195
196196static SILValue getUnderlyingTrackedObjectValue (SILValue value) {
197+ auto *fn = value->getFunction ();
197198 SILValue result = value;
198199 while (true ) {
199200 SILValue temp = result;
200201
201- temp = getUnderlyingObject (temp);
202+ temp = stripSinglePredecessorArgs (temp);
203+ temp = stripAddressProjections (temp);
204+ temp = stripIndexingInsts (temp);
205+ temp = lookThroughOwnershipInsts (temp);
202206
203207 if (auto *svi = dyn_cast<SingleValueInstruction>(temp)) {
204208 if (isa<ExplicitCopyValueInst, CopyableToMoveOnlyWrapperValueInst,
205209 MoveOnlyWrapperToCopyableValueInst,
206- MoveOnlyWrapperToCopyableBoxInst>(svi)) {
210+ MoveOnlyWrapperToCopyableBoxInst, BeginAccessInst,
211+ MarkDependenceInst>(svi) ||
212+ isIdentityPreservingRefCast (svi)) {
207213 temp = svi->getOperand (0 );
208214 }
215+
216+ // If we have a cast and our operand and result are non-Sendable, treat it
217+ // as a look through.
218+ if (isa<UncheckedTrivialBitCastInst, UncheckedBitwiseCastInst,
219+ UncheckedValueCastInst>(svi)) {
220+ if (isNonSendableType (svi->getType (), fn) &&
221+ isNonSendableType (svi->getOperand (0 )->getType (), fn)) {
222+ temp = svi->getOperand (0 );
223+ }
224+ }
225+ }
226+
227+ if (auto *r = dyn_cast<RefToRawPointerInst>(temp)) {
228+ // If our operand is a non-Sendable type, look through this instruction.
229+ if (isNonSendableType (r->getOperand ()->getType (), fn)) {
230+ temp = r->getOperand ();
231+ }
232+ }
233+
234+ if (auto *r = dyn_cast<RawPointerToRefInst>(temp)) {
235+ // If our result is a non-Sendable type, look through this
236+ // instruction. Builtin.RawPointer is always non-Sendable.
237+ if (isNonSendableType (r->getType (), fn)) {
238+ temp = r->getOperand ();
239+ }
209240 }
210241
211242 if (auto *dsi = dyn_cast_or_null<DestructureStructInst>(
@@ -2321,6 +2352,7 @@ CONSTANT_TRANSLATION(UncheckedAddrCastInst, Assign)
23212352CONSTANT_TRANSLATION(UncheckedEnumDataInst, Assign)
23222353CONSTANT_TRANSLATION(UncheckedOwnershipConversionInst, Assign)
23232354CONSTANT_TRANSLATION(UnmanagedToRefInst, Assign)
2355+ CONSTANT_TRANSLATION(IndexRawPointerInst, Assign)
23242356
23252357// These are used by SIL to aggregate values together in a gep like way. We
23262358// want to look at uses of structs, not the struct uses itself. So just
@@ -2434,17 +2466,22 @@ CONSTANT_TRANSLATION(CondBranchInst, TerminatorPhi)
24342466CONSTANT_TRANSLATION(CheckedCastBranchInst, TerminatorPhi)
24352467CONSTANT_TRANSLATION(DynamicMethodBranchInst, TerminatorPhi)
24362468
2469+ // ===---
2470+ // Existential Box
2471+ //
2472+
2473+ // NOTE: Today these can only be used with Errors. Since Error is a sub-protocol
2474+ // of Sendable, we actually do not have any way to truly test them. These are
2475+ // just hypothetical assignments so we are complete.
2476+ CONSTANT_TRANSLATION(AllocExistentialBoxInst, AssignFresh)
2477+ CONSTANT_TRANSLATION(ProjectExistentialBoxInst, Assign)
2478+ CONSTANT_TRANSLATION(OpenExistentialBoxValueInst, Assign)
2479+ CONSTANT_TRANSLATION(DeallocExistentialBoxInst, Ignored)
2480+
24372481// ===---
24382482// Unhandled Instructions
24392483//
24402484
2441- CONSTANT_TRANSLATION(AllocExistentialBoxInst, Unhandled)
2442- CONSTANT_TRANSLATION(IndexRawPointerInst, Unhandled)
2443- CONSTANT_TRANSLATION(UncheckedTrivialBitCastInst, Unhandled)
2444- CONSTANT_TRANSLATION(UncheckedBitwiseCastInst, Unhandled)
2445- CONSTANT_TRANSLATION(UncheckedValueCastInst, Unhandled)
2446- CONSTANT_TRANSLATION(RefToRawPointerInst, Unhandled)
2447- CONSTANT_TRANSLATION(RawPointerToRefInst, Unhandled)
24482485CONSTANT_TRANSLATION(RefToUnownedInst, Unhandled)
24492486CONSTANT_TRANSLATION(UnownedToRefInst, Unhandled)
24502487CONSTANT_TRANSLATION(BridgeObjectToWordInst, Unhandled)
@@ -2460,7 +2497,6 @@ CONSTANT_TRANSLATION(StrongCopyUnmanagedValueInst, Unhandled)
24602497CONSTANT_TRANSLATION(DropDeinitInst, Unhandled)
24612498CONSTANT_TRANSLATION(IsUniqueInst, Unhandled)
24622499CONSTANT_TRANSLATION(LoadUnownedInst, Unhandled)
2463- CONSTANT_TRANSLATION(ProjectExistentialBoxInst, Unhandled)
24642500CONSTANT_TRANSLATION(ValueMetatypeInst, Unhandled)
24652501CONSTANT_TRANSLATION(ExistentialMetatypeInst, Unhandled)
24662502CONSTANT_TRANSLATION(VectorInst, Unhandled)
@@ -2472,7 +2508,6 @@ CONSTANT_TRANSLATION(InitExistentialValueInst, Unhandled)
24722508CONSTANT_TRANSLATION(InitExistentialMetatypeInst, Unhandled)
24732509CONSTANT_TRANSLATION(OpenExistentialMetatypeInst, Unhandled)
24742510CONSTANT_TRANSLATION(OpenExistentialValueInst, Unhandled)
2475- CONSTANT_TRANSLATION(OpenExistentialBoxValueInst, Unhandled)
24762511CONSTANT_TRANSLATION(OpenPackElementInst, Unhandled)
24772512CONSTANT_TRANSLATION(PackLengthInst, Unhandled)
24782513CONSTANT_TRANSLATION(DynamicPackIndexInst, Unhandled)
@@ -2494,7 +2529,6 @@ CONSTANT_TRANSLATION(DeallocPackInst, Unhandled)
24942529CONSTANT_TRANSLATION(DeallocStackRefInst, Unhandled)
24952530CONSTANT_TRANSLATION(DeallocRefInst, Unhandled)
24962531CONSTANT_TRANSLATION(DeallocPartialRefInst, Unhandled)
2497- CONSTANT_TRANSLATION(DeallocExistentialBoxInst, Unhandled)
24982532CONSTANT_TRANSLATION(UnmanagedRetainValueInst, Unhandled)
24992533CONSTANT_TRANSLATION(UnmanagedReleaseValueInst, Unhandled)
25002534CONSTANT_TRANSLATION(UnmanagedAutoreleaseValueInst, Unhandled)
@@ -2593,10 +2627,62 @@ IGNORE_IF_SENDABLE_RESULT_ASSIGN_OTHERWISE(StructExtractInst)
25932627
25942628#undef IGNORE_IF_SENDABLE_RESULT_ASSIGN_OTHERWISE
25952629
2630+ #ifdef CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT
2631+ #error "CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT already defined"
2632+ #endif
2633+
2634+ #define CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT (INST ) \
2635+ \
2636+ TranslationSemantics PartitionOpTranslator::visit##INST(INST *cast) { \
2637+ bool isOperandNonSendable = \
2638+ isNonSendableType (cast->getOperand ()->getType ()); \
2639+ bool isResultNonSendable = isNonSendableType (cast->getType ()); \
2640+ \
2641+ if (isOperandNonSendable) { \
2642+ if (isResultNonSendable) { \
2643+ return TranslationSemantics::LookThrough; \
2644+ } \
2645+ \
2646+ return TranslationSemantics::Require; \
2647+ } \
2648+ \
2649+ if (isResultNonSendable) \
2650+ return TranslationSemantics::AssignFresh; \
2651+ \
2652+ return TranslationSemantics::Ignored; \
2653+ }
2654+
2655+ CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT (UncheckedTrivialBitCastInst)
2656+ CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT(UncheckedBitwiseCastInst)
2657+ CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT(UncheckedValueCastInst)
2658+
2659+ #undef CAST_WITH_MAYBE_SENDABLE_NONSENDABLE_OP_AND_RESULT
2660+
25962661// ===---
25972662// Custom Handling
25982663//
25992664
2665+ TranslationSemantics
2666+ PartitionOpTranslator::visitRawPointerToRefInst (RawPointerToRefInst *r) {
2667+ // If our result is non sendable, perform a look through.
2668+ if (isNonSendableType (r->getType ()))
2669+ return TranslationSemantics::LookThrough;
2670+
2671+ // Otherwise to be conservative, we need to treat this as a require.
2672+ return TranslationSemantics::Require;
2673+ }
2674+
2675+ TranslationSemantics
2676+ PartitionOpTranslator::visitRefToRawPointerInst (RefToRawPointerInst *r) {
2677+ // If our source ref is non sendable, perform a look through.
2678+ if (isNonSendableType (r->getOperand ()->getType ()))
2679+ return TranslationSemantics::LookThrough;
2680+
2681+ // Otherwise to be conservative, we need to treat the raw pointer as a fresh
2682+ // sendable value.
2683+ return TranslationSemantics::AssignFresh;
2684+ }
2685+
26002686TranslationSemantics
26012687PartitionOpTranslator::visitMarkDependenceInst (MarkDependenceInst *mdi) {
26022688 translateSILAssign (mdi, mdi->getValue ());
0 commit comments