Skip to content

Commit c3c84d3

Browse files
authored
Merge pull request #67421 from JTurcotti/more-diags
[SendNonSendable] Improve diagnostics and fix bugs
2 parents c27e2c7 + 853ef7c commit c3c84d3

File tree

6 files changed

+512
-192
lines changed

6 files changed

+512
-192
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -864,14 +864,16 @@ NOTE(sil_referencebinding_inout_binding_here, none,
864864

865865
// Warnings arising from the flow-sensitive checking of Sendability of
866866
// non-Sendable values
867-
WARNING(consumed_value_used, none,
868-
"non-Sendable value consumed, then used at this site; could yield race with another thread", ())
869867
WARNING(arg_region_consumed, none,
870-
"this application could pass `self` or a Non-Sendable argument of this function to another thread, potentially yielding a race with the caller", ())
868+
"call site passes `self` or a non-sendable argument of this function to another thread, potentially yielding a race with the caller", ())
871869
WARNING(consumption_yields_race, none,
872-
"non-Sendable value sent across isolation domains here, but could be accessed later in this function (%0 access site%select{|s}1 displayed%select{|, %3 more hidden}2)", (unsigned, bool, bool, unsigned))
870+
"non-sendable value sent across isolation domains that could be concurrently accessed later in this function (%0 access site%select{|s}1 displayed%select{|, %3 more hidden}2)",
871+
(unsigned, bool, bool, unsigned))
872+
WARNING(call_site_consumption_yields_race, none,
873+
"passing argument of non-sendable type %0 from %1 context to %2 context at this call site could yield a race with accesses later in this function (%3 access site%select{|s}4 displayed%select{|, %6 more hidden}5)",
874+
(Type, ActorIsolation, ActorIsolation, unsigned, bool, bool, unsigned))
873875
NOTE(possible_racy_access_site, none,
874-
"access here could race with non-Sendable value send above", ())
876+
"access here could race", ())
875877

876878
#define UNDEFINE_DIAGNOSTIC_MACROS
877879
#include "DefineDiagnosticMacros.h"

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,16 @@ class PartitionOp {
127127
}
128128

129129
bool operator==(const PartitionOp &other) const {
130-
return OpKind == other.OpKind && sourceInst == other.sourceInst;
130+
return OpKind == other.OpKind
131+
&& OpArgs == other.OpArgs
132+
&& sourceInst == other.sourceInst;
131133
};
132134
// implemented for insertion into std::map
133135
bool operator<(const PartitionOp &other) const {
134136
if (OpKind != other.OpKind)
135137
return OpKind < other.OpKind;
138+
if (OpArgs != other.OpArgs)
139+
return OpArgs < other.OpArgs;
136140
return sourceInst < other.sourceInst;
137141
}
138142

@@ -145,6 +149,10 @@ class PartitionOp {
145149
return sourceInst;
146150
}
147151

152+
Expr *getSourceExpr() const {
153+
return sourceExpr;
154+
}
155+
148156
void dump() const LLVM_ATTRIBUTE_USED {
149157
raw_ostream &os = llvm::errs();
150158
switch (OpKind) {
@@ -440,25 +448,26 @@ class Partition {
440448
assert(labels.count(op.OpArgs[0]) &&
441449
"Consume PartitionOp's argument should already be tracked");
442450

443-
// if attempting to consume a consumed region, handle the failure
444-
if (isConsumed(op.OpArgs[0]))
445-
handleFailure(op, op.OpArgs[0]);
446-
447-
// mark region as consumed
448-
horizontalUpdate(labels, op.OpArgs[0], Region::consumed());
449-
450-
// check if any nonconsumables were consumed, and handle the failure if so
451+
// check if any nonconsumables are consumed here, and handle the failure if so
451452
for (Element nonconsumable : nonconsumables) {
452453
assert(labels.count(nonconsumable) &&
453454
"nonconsumables should be function args and self, and therefore"
454455
"always present in the label map because of initialization at "
455456
"entry");
456-
if (isConsumed(nonconsumable)) {
457+
if (!isConsumed(nonconsumable) &&
458+
labels.at(nonconsumable) == labels.at(op.OpArgs[0])) {
457459
handleConsumeNonConsumable(op, nonconsumable);
458460
break;
459461
}
460462
}
461463

464+
// ensure region is consumed
465+
if (!isConsumed(op.OpArgs[0]))
466+
// mark region as consumed
467+
horizontalUpdate(labels, op.OpArgs[0], Region::consumed());
468+
469+
470+
462471
break;
463472
case PartitionOpKind::Merge:
464473
assert(op.OpArgs.size() == 2 &&
@@ -523,7 +532,7 @@ class Partition {
523532
llvm::dbgs() << "}\n";
524533
}
525534

526-
void dump() LLVM_ATTRIBUTE_USED {
535+
void dump() const LLVM_ATTRIBUTE_USED {
527536
std::map<Region, std::vector<Element>> buckets;
528537

529538
for (auto [i, label] : labels)

0 commit comments

Comments
 (0)