Skip to content

Commit fc73210

Browse files
committed
[region-isolation] Do not look through type casts from a non-Sendable to a Sendable value.
This came up while I was debugging test cases from the other parts of this work. The specific issue was around a pointer_to_address from a RawPointer (which is considered non-Sendable) to a Sendable type. We were identifying the RawPointer as being the representative of the Sendable value implying we were processing Sendable values like they were non-Sendable. =><=. I wish we had SIL test cases for region isolation since I would add one for this...
1 parent 9e3f0b0 commit fc73210

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ static bool isIsolationBoundaryCrossingApply(const SILInstruction *inst) {
5454
return false;
5555
}
5656

57+
/// Check if the passed in type is NonSendable.
58+
///
59+
/// NOTE: We special case RawPointer and NativeObject to ensure they are
60+
/// treated as non-Sendable and strict checking is applied to it.
61+
static bool isNonSendableType(SILType type, SILFunction *fn) {
62+
// Treat Builtin.NativeObject and Builtin.RawPointer as non-Sendable.
63+
if (type.getASTType()->is<BuiltinNativeObjectType>() ||
64+
type.getASTType()->is<BuiltinRawPointerType>()) {
65+
return true;
66+
}
67+
68+
// Otherwise, delegate to seeing if type conforms to the Sendable protocol.
69+
return !type.isSendable(fn);
70+
}
71+
5772
namespace {
5873

5974
struct UseDefChainVisitor
@@ -93,10 +108,17 @@ struct UseDefChainVisitor
93108
return visitAll(access->getSource());
94109
}
95110

96-
SILValue visitStorageCast(SingleValueInstruction *, Operand *sourceAddr,
111+
SILValue visitStorageCast(SingleValueInstruction *cast, Operand *sourceAddr,
97112
AccessStorageCast castType) {
113+
// If this is a type case, see if the result of the cast is sendable. In
114+
// such a case, we do not want to look through this cast.
115+
if (castType == AccessStorageCast::Type &&
116+
!isNonSendableType(cast->getType(), cast->getFunction()))
117+
return SILValue();
118+
98119
// If we do not have an identity cast, mark this as a merge.
99120
isMerge |= castType != AccessStorageCast::Identity;
121+
100122
return sourceAddr->get();
101123
}
102124

@@ -623,14 +645,7 @@ class PartitionOpTranslator {
623645
/// NOTE: We special case RawPointer and NativeObject to ensure they are
624646
/// treated as non-Sendable and strict checking is applied to it.
625647
bool isNonSendableType(SILType type) const {
626-
// Treat Builtin.NativeObject and Builtin.RawPointer as non-Sendable.
627-
if (type.getASTType()->is<BuiltinNativeObjectType>() ||
628-
type.getASTType()->is<BuiltinRawPointerType>()) {
629-
return true;
630-
}
631-
632-
// Otherwise, delegate to seeing if type conforms to the Sendable protocol.
633-
return !type.isSendable(function);
648+
return ::isNonSendableType(type, function);
634649
}
635650

636651
// ===========================================================================

0 commit comments

Comments
 (0)