Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 40 additions & 39 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,12 @@ ERROR(missing_never_call_closure,none,
(Type))

ERROR(missing_return_decl,none,
"missing return in %1 expected to return %0",
(Type, DescriptiveDeclKind))
"missing return in %kindonly1 expected to return %0",
(Type, const AbstractFunctionDecl *))
ERROR(missing_never_call_decl,none,
"%1 with uninhabited return type %0 is missing "
"%kindonly1 with uninhabited return type %0 is missing "
"call to another never-returning function on all paths",
(Type, DescriptiveDeclKind))
(Type, const AbstractFunctionDecl *))

NOTE(missing_return_last_expr_note,none,
"did you mean to return the last expression?", ())
Expand Down Expand Up @@ -701,8 +701,9 @@ WARNING(warning_int_to_fp_inexact, none,

// Flow-isolation diagnostics
ERROR(isolated_after_nonisolated, none,
"cannot access %1 %2 here in %select{nonisolated initializer|deinitializer}0",
(bool, DescriptiveDeclKind, DeclName))
"cannot access %kind1 here in "
"%select{nonisolated initializer|deinitializer}0",
(bool, const ValueDecl *))
NOTE(nonisolated_blame, none, "after %1%2 %3, "
"only nonisolated properties of 'self' can be accessed from "
"%select{this init|a deinit}0", (bool, StringRef, StringRef, DeclName))
Expand Down Expand Up @@ -982,23 +983,23 @@ GROUPED_ERROR(regionbasedisolation_type_send_yields_race, SendingRisksDataRace,
(Type))
NOTE(regionbasedisolation_type_use_after_send, none,
"sending value of non-Sendable type %0 to %1 callee risks causing data races between %1 and local %2 uses",
(Type, ActorIsolation, ActorIsolation))
(Type, StringRef, StringRef))
NOTE(regionbasedisolation_type_use_after_send_callee, none,
"sending value of non-Sendable type %0 to %1 %2 %3 risks causing data "
"races between %1 and local %4 uses",
(Type, ActorIsolation, DescriptiveDeclKind, DeclName, ActorIsolation))
"sending value of non-Sendable type %0 to %1 %kind2 risks causing data "
"races between %1 and local %3 uses",
(Type, StringRef, const ValueDecl *, StringRef))

NOTE(regionbasedisolation_named_info_send_yields_race, none,
"sending %1%0 to %2 callee risks causing data races between %2 and local %3 uses",
(Identifier, StringRef, ActorIsolation, ActorIsolation))
"sending %select{%2 |}0%1 to %3 callee risks causing data races between %3 and local %4 uses",
(bool, Identifier, StringRef, StringRef, StringRef))
NOTE(regionbasedisolation_named_info_send_yields_race_callee, none,
"sending %1%0 to %2 %3 %4 risks causing data races between %2 and local %5 uses",
(Identifier, StringRef, ActorIsolation, DescriptiveDeclKind, DeclName, ActorIsolation))
"sending %select{%2 |}0%1 to %3 %kind4 risks causing data races between %3 and local %5 uses",
(bool, Identifier, StringRef, StringRef, const ValueDecl *, StringRef))

// Use after send closure.
NOTE(regionbasedisolation_type_isolated_capture_yields_race, none,
"sending value of non-Sendable type %0 to %1 closure due to closure capture risks causing races in between %1 and %2 uses",
(Type, ActorIsolation, ActorIsolation))
(Type, StringRef, StringRef))

// Value captured in async let and reused.
NOTE(regionbasedisolation_named_nonisolated_asynclet_name, none,
Expand All @@ -1009,33 +1010,33 @@ NOTE(regionbasedisolation_named_value_used_after_explicit_sending, none,
"%0 used after being passed as a 'sending' parameter; Later uses could race",
(Identifier))
NOTE(regionbasedisolation_named_isolated_closure_yields_race, none,
"%0%1 is captured by a %2 closure. %2 uses in closure may race against later %3 uses",
(StringRef, Identifier, ActorIsolation, ActorIsolation))
"%select{%1 |}0%2 is captured by a %3 closure. %3 uses in closure may race against later %4 uses",
(bool, StringRef, Identifier, StringRef, StringRef))

NOTE(regionbasedisolation_typed_use_after_sending, none,
"Passing value of non-Sendable type %0 as a 'sending' argument risks causing races in between local and caller code",
(Type))
NOTE(regionbasedisolation_typed_use_after_sending_callee, none,
"Passing value of non-Sendable type %0 as a 'sending' argument to %1 %2 risks causing races in between local and caller code",
(Type, DescriptiveDeclKind, DeclName))
"Passing value of non-Sendable type %0 as a 'sending' argument to %kind1 risks causing races in between local and caller code",
(Type, const ValueDecl *))

//===
// Sending Never Sendable Emitter

NOTE(regionbasedisolation_named_send_never_sendable, none,
"sending %1%0 to %2 callee risks causing data races between %2 and %3 uses",
(Identifier, StringRef, ActorIsolation, StringRef))
"sending %select{%2 |}0%1 to %3 callee risks causing data races between %3 and %4 uses",
(bool, Identifier, StringRef, StringRef, StringRef))
NOTE(regionbasedisolation_named_send_never_sendable_callee, none,
"sending %1%0 to %2 %3 %4 risks causing data races between %2 and %5 uses",
(Identifier, StringRef, ActorIsolation, DescriptiveDeclKind, DeclName, StringRef))
"sending %select{%2 |}0%1 to %3 %kind4 risks causing data races between %3 and %5 uses",
(bool, Identifier, StringRef, StringRef, const ValueDecl *, StringRef))

NOTE(regionbasedisolation_named_send_into_sending_param, none,
"%0%1 is passed as a 'sending' parameter; Uses in callee may race with "
"later %0uses",
(StringRef, Identifier))
"%select{%1 |}0%2 is passed as a 'sending' parameter; Uses in callee may race with "
"later %1 uses",
(bool, StringRef, Identifier))
NOTE(regionbasedisolation_named_nosend_send_into_result, none,
"%0%1 cannot be a 'sending' result. %2 uses may race with caller uses",
(StringRef, Identifier, StringRef))
"%select{%1 |}0%2 cannot be a 'sending' result. %3 uses may race with caller uses",
(bool, StringRef, Identifier, StringRef))
NOTE(regionbasedisolation_typed_tns_passed_to_sending, none,
"Passing %0 value of non-Sendable type %1 as a 'sending' parameter risks "
"causing races inbetween %0 uses and uses reachable from the callee",
Expand All @@ -1051,8 +1052,8 @@ NOTE(regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_value_
"closure captures %0 which is accessible to code in the current task",
(DeclName))
NOTE(regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_boxed_value_task_isolated, none,
"closure captures reference to mutable %1 %0 which is accessible to code in the current task",
(DeclName, DescriptiveDeclKind))
"closure captures reference to mutable %kind0 which is accessible to code in the current task",
(const ValueDecl *))
NOTE(regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_value_region, none,
"closure captures %1 which is accessible to %0 code",
(StringRef, DeclName))
Expand All @@ -1068,18 +1069,18 @@ NOTE(regionbasedisolation_closure_captures_actor, none,
(DeclName, StringRef))

NOTE(regionbasedisolation_typed_tns_passed_to_sending_callee, none,
"Passing %0 value of non-Sendable type %1 as a 'sending' parameter to %2 %3 risks causing races inbetween %0 uses and uses reachable from %3",
(StringRef, Type, DescriptiveDeclKind, DeclName))
"Passing %0 value of non-Sendable type %1 as a 'sending' parameter to %kind2 risks causing races inbetween %0 uses and uses reachable from %2",
(StringRef, Type, const ValueDecl *))

NOTE(regionbasedisolation_named_send_nt_asynclet_capture, none,
"sending %1 %0 into async let risks causing data races between nonisolated and %1 uses",
(Identifier, StringRef))
NOTE(regionbasedisolation_typed_sendneversendable_via_arg, none,
"sending %0 value of non-Sendable type %1 to %2 callee risks causing races in between %0 and %2 uses",
(StringRef, Type, ActorIsolation))
(StringRef, Type, StringRef))
NOTE(regionbasedisolation_typed_sendneversendable_via_arg_callee, none,
"sending %0 value of non-Sendable type %1 to %2 %3 %4 risks causing races in between %0 and %2 uses",
(StringRef, Type, ActorIsolation, DescriptiveDeclKind, DeclName))
"sending %0 value of non-Sendable type %1 to %2 %kind3 risks causing races in between %0 and %2 uses",
(StringRef, Type, StringRef, const ValueDecl *))

NOTE(regionbasedisolation_isolated_conformance_introduced, none,
"isolated conformance to %kind0 can be introduced here",
Expand All @@ -1097,10 +1098,10 @@ NOTE(regionbasedisolation_inout_sending_must_be_reinitialized, none,
"'inout sending' parameter must be reinitialized before function exit with a non-actor isolated value",
())
ERROR(regionbasedisolation_inout_sending_cannot_be_actor_isolated, none,
"'inout sending' parameter %0 cannot be %1at end of function",
"'inout sending' parameter %0 cannot be %1 at end of function",
(Identifier, StringRef))
NOTE(regionbasedisolation_inout_sending_cannot_be_actor_isolated_note, none,
"%1%0 risks causing races in between %1uses and caller uses since caller assumes value is not actor isolated",
"%1 %0 risks causing races in between %1 uses and caller uses since caller assumes value is not actor isolated",
(Identifier, StringRef))

//===
Expand All @@ -1125,10 +1126,10 @@ NOTE(regionbasedisolation_out_sending_cannot_be_actor_isolated_note_named, none,
// Example: returning main-actor isolated result to a custom-actor isolated context risks causing data races
ERROR(rbi_isolation_crossing_result, none,
"non-Sendable %0-typed result can not be returned from %1 %kind2 to %3 context",
(Type, ActorIsolation, const ValueDecl *, ActorIsolation))
(Type, StringRef, const ValueDecl *, StringRef))
ERROR(rbi_isolation_crossing_result_no_decl, none,
"non-Sendable %0-typed result can not be returned from %1 function to %2 context",
(Type, ActorIsolation, ActorIsolation))
(Type, StringRef, StringRef))
NOTE(rbi_non_sendable_nominal,none,
"%kind0 does not conform to the 'Sendable' protocol",
(const ValueDecl *))
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/Identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ class Identifier {
private:
bool isOperatorSlow() const;
};

class DeclName;
class DeclNameRef;
class ObjCSelector;
Expand Down
28 changes: 15 additions & 13 deletions include/swift/SILOptimizer/Analysis/RegionAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,16 +179,16 @@ class regionanalysisimpl::TrackableValueState {

void removeFlag(TrackableValueFlag flag) { flagSet -= flag; }

void print(llvm::raw_ostream &os) const {
void print(SILFunction *fn, llvm::raw_ostream &os) const {
os << "TrackableValueState[id: " << id
<< "][is_no_alias: " << (isNoAlias() ? "yes" : "no")
<< "][is_sendable: " << (isSendable() ? "yes" : "no")
<< "][region_value_kind: ";
getIsolationRegionInfo().printForOneLineLogging(os);
getIsolationRegionInfo().printForOneLineLogging(fn, os);
os << "].";
}

SWIFT_DEBUG_DUMP { print(llvm::dbgs()); }
SWIFT_DEBUG_DUMPER(dump(SILFunction *fn)) { print(fn, llvm::dbgs()); }

private:
bool hasIsolationRegionInfo() const { return bool(regionInfo); }
Expand Down Expand Up @@ -249,26 +249,26 @@ class regionanalysisimpl::TrackableValue {
/// parameter.
bool isSendingParameter() const;

void printIsolationInfo(SmallString<64> &outString) const {
void printIsolationInfo(SILFunction *fn, SmallString<64> &outString) const {
llvm::raw_svector_ostream os(outString);
getIsolationRegionInfo().printForDiagnostics(os);
getIsolationRegionInfo().printForDiagnostics(fn, os);
}

void print(llvm::raw_ostream &os) const {
void print(SILFunction *fn, llvm::raw_ostream &os) const {
os << "TrackableValue. State: ";
valueState.print(os);
valueState.print(fn, os);
os << "\n Rep Value: ";
getRepresentative().print(os);
}

void printVerbose(llvm::raw_ostream &os) const {
void printVerbose(SILFunction *fn, llvm::raw_ostream &os) const {
os << "TrackableValue. State: ";
valueState.print(os);
valueState.print(fn, os);
os << "\n Rep Value: " << getRepresentative();
}

SWIFT_DEBUG_DUMP {
print(llvm::dbgs());
SWIFT_DEBUG_DUMPER(dump(SILFunction *fn)) {
print(fn, llvm::dbgs());
llvm::dbgs() << '\n';
}
};
Expand All @@ -288,8 +288,8 @@ struct regionanalysisimpl::TrackableValueLookupResult {
/// TrackableValue.
std::optional<TrackableValue> base;

void print(llvm::raw_ostream &os) const;
SWIFT_DEBUG_DUMP { print(llvm::dbgs()); }
void print(SILFunction *fn, llvm::raw_ostream &os) const;
SWIFT_DEBUG_DUMPER(dumper(SILFunction *fn)) { print(fn, llvm::dbgs()); }
};

class RegionAnalysis;
Expand Down Expand Up @@ -390,6 +390,8 @@ class RegionAnalysisValueMap {
return getUnderlyingTrackedValue(value).value;
}

SILFunction *getFunction() const { return fn; }

/// Returns the value for this instruction if it isn't a fake "represenative
/// value" to inject actor isolatedness. Asserts in such a case.
SILValue getRepresentative(Element trackableValueID) const;
Expand Down
32 changes: 29 additions & 3 deletions include/swift/SILOptimizer/Utils/PartitionUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1598,9 +1598,32 @@ struct PartitionOpEvaluator {
}

private:
bool isConvertFunctionFromSendableType(SILValue equivalenceClassRep) const {
/// To work around not having isolation in interface types, the type checker
/// inserts casts and other AST nodes that are used to enrich the AST with
/// isolation information. This results in Sendable functions being
/// wrapped/converted/etc in ways that hide the Sendability. This helper looks
/// through these conversions/wrappers/thunks to see if the original
/// underlying function is Sendable.
///
/// The two ways this can happen is that we either get an actual function_ref
/// that is Sendable or we get a convert function with a Sendable operand.
bool isHiddenSendableFunctionType(SILValue equivalenceClassRep) const {
SILValue valueToTest = equivalenceClassRep;
while (true) {
if (auto *pai = dyn_cast<PartialApplyInst>(valueToTest)) {
if (auto *calleeFunction = pai->getCalleeFunction()) {
if (pai->getNumArguments() >= 1 &&
pai->getArgument(0)->getType().isFunction() &&
calleeFunction->isThunk()) {
valueToTest = pai->getArgument(0);
continue;
}

if (calleeFunction->getLoweredFunctionType()->isSendable())
return true;
}
}

if (auto *i = dyn_cast<ThinToThickFunctionInst>(valueToTest)) {
valueToTest = i->getOperand();
continue;
Expand All @@ -1612,6 +1635,9 @@ struct PartitionOpEvaluator {
break;
}

if (auto *fn = dyn_cast<FunctionRefInst>(valueToTest))
return fn->getReferencedFunction()->getLoweredFunctionType()->isSendable();

auto *cvi = dyn_cast<ConvertFunctionInst>(valueToTest);
if (!cvi)
return false;
Expand Down Expand Up @@ -1644,7 +1670,7 @@ struct PartitionOpEvaluator {

// See if we have a convert function from a `@Sendable` type. In this
// case, we want to squelch the error.
if (isConvertFunctionFromSendableType(equivalenceClassRep))
if (isHiddenSendableFunctionType(equivalenceClassRep))
return;
}

Expand Down Expand Up @@ -1689,7 +1715,7 @@ struct PartitionOpEvaluator {

// See if we have a convert function from a `@Sendable` type. In this
// case, we want to squelch the error.
if (isConvertFunctionFromSendableType(equivalenceClassRep))
if (isHiddenSendableFunctionType(equivalenceClassRep))
return;
}
}
Expand Down
Loading