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
48 changes: 24 additions & 24 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -998,23 +998,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 %kind2 risks causing data "
"races between %1 and local %3 uses",
(Type, ActorIsolation, const ValueDecl *, ActorIsolation))
(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 %kind3 risks causing data races between %2 and local %4 uses",
(Identifier, StringRef, ActorIsolation, const ValueDecl *, 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 @@ -1025,8 +1025,8 @@ 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",
Expand All @@ -1039,19 +1039,19 @@ NOTE(regionbasedisolation_typed_use_after_sending_callee, none,
// 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 %kind3 risks causing data races between %2 and %4 uses",
(Identifier, StringRef, ActorIsolation, const ValueDecl *, 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 Down Expand Up @@ -1092,10 +1092,10 @@ NOTE(regionbasedisolation_named_send_nt_asynclet_capture, none,
(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 %kind3 risks causing races in between %0 and %2 uses",
(StringRef, Type, ActorIsolation, const ValueDecl *))
(StringRef, Type, StringRef, const ValueDecl *))

// Error that is only used when the send non sendable emitter cannot discover any
// information to give a better diagnostic.
Expand All @@ -1109,10 +1109,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 @@ -1137,10 +1137,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 isolation. Asserts in such a case.
SILValue getRepresentative(Element trackableValueID) const;
Expand Down
104 changes: 69 additions & 35 deletions include/swift/SILOptimizer/Utils/SILIsolationInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ class SILIsolationInfo {
/// parameter and should be allowed to merge into a self parameter.
UnappliedIsolatedAnyParameter = 0x2,

/// If set, this was a TaskIsolated value from a nonisolated(nonsending)
/// parameter.
NonisolatedNonsendingTaskIsolated = 0x4,

/// The maximum number of bits used by a Flag.
MaxNumBits = 2,
};
Expand Down Expand Up @@ -269,6 +273,25 @@ class SILIsolationInfo {
return self;
}

bool isNonisolatedNonsendingTaskIsolated() const {
return getOptions().contains(Flag::NonisolatedNonsendingTaskIsolated);
}

SILIsolationInfo
withNonisolatedNonsendingTaskIsolated(bool newValue = true) const {
assert(*this && "Cannot be unknown");
assert(isTaskIsolated() && "Can only be task isolated");
auto self = *this;
if (newValue) {
self.options =
(self.getOptions() | Flag::NonisolatedNonsendingTaskIsolated).toRaw();
} else {
self.options = self.getOptions().toRaw() &
~Options(Flag::NonisolatedNonsendingTaskIsolated).toRaw();
}
return self;
}

/// Returns true if this actor isolation is derived from an unapplied
/// isolation parameter. When merging, we allow for this to be merged with a
/// more specific isolation kind.
Expand All @@ -289,16 +312,16 @@ class SILIsolationInfo {
return self;
}

void print(llvm::raw_ostream &os) const;
void print(SILFunction *fn, llvm::raw_ostream &os) const;

/// Print a textual representation of the text info that is meant to be
/// included in other logging output for types that compose with
/// SILIsolationInfo. As a result, we only print state that can fit on
/// one line.
void printForOneLineLogging(llvm::raw_ostream &os) const;
void printForOneLineLogging(SILFunction *fn, llvm::raw_ostream &os) const;

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

Expand All @@ -307,12 +330,20 @@ class SILIsolationInfo {
///
/// We do this programatically since task-isolated code needs a very different
/// form of diagnostic than other cases.
void printForCodeDiagnostic(llvm::raw_ostream &os) const;
void printForCodeDiagnostic(SILFunction *fn, llvm::raw_ostream &os) const;

/// Overload of printForCodeDiagnostics that returns an interned StringRef
/// owned by the AST.
StringRef printForCodeDiagnostic(SILFunction *fn) const;

void printForDiagnostics(llvm::raw_ostream &os) const;
void printForDiagnostics(SILFunction *fn, llvm::raw_ostream &os) const;

SWIFT_DEBUG_DUMPER(dumpForDiagnostics()) {
printForDiagnostics(llvm::dbgs());
/// Overload of printForDiagnostics that returns an interned StringRef owned
/// by the AST.
StringRef printForDiagnostics(SILFunction *fn) const;

SWIFT_DEBUG_DUMPER(dumpForDiagnostics(SILFunction *fn)) {
printForDiagnostics(fn, llvm::dbgs());
llvm::dbgs() << '\n';
}

Expand Down Expand Up @@ -494,6 +525,19 @@ class SILIsolationInfo {
/// that the isolation and the isolated value match.
bool isEqual(const SILIsolationInfo &other) const;

/// A helper function that prints ActorIsolation like we normally do except
/// that it prints nonisolated(nonsending) as nonisolated. This is needed in
/// certain cases when talking about use-after-free uses in send non sendable.
static void printActorIsolationForDiagnostics(
SILFunction *fn, ActorIsolation iso, llvm::raw_ostream &os,
StringRef openingQuotationMark = "'", bool asNoun = false);

/// Overload for printActorIsolationForDiagnostics that produces a StringRef.
static StringRef
printActorIsolationForDiagnostics(SILFunction *fn, ActorIsolation iso,
StringRef openingQuotationMark = "'",
bool asNoun = false);

void Profile(llvm::FoldingSetNodeID &id) const;

private:
Expand Down Expand Up @@ -557,43 +601,33 @@ class SILDynamicMergedIsolationInfo {
SILIsolationInfo::getDisconnected(isUnsafeNonIsolated));
}

SWIFT_DEBUG_DUMP { innerInfo.dump(); }
SWIFT_DEBUG_DUMPER(dump(SILFunction *fn)) { innerInfo.dump(fn); }

void printForDiagnostics(llvm::raw_ostream &os) const {
innerInfo.printForDiagnostics(os);
void printForDiagnostics(SILFunction *fn, llvm::raw_ostream &os) const {
innerInfo.printForDiagnostics(fn, os);
}

SWIFT_DEBUG_DUMPER(dumpForDiagnostics()) {
innerInfo.dumpForDiagnostics();
StringRef printForDiagnostics(SILFunction *fn) const {
return innerInfo.printForDiagnostics(fn);
}

void printForCodeDiagnostic(llvm::raw_ostream &os) const {
innerInfo.printForCodeDiagnostic(os);
SWIFT_DEBUG_DUMPER(dumpForDiagnostics(SILFunction *fn)) {
innerInfo.dumpForDiagnostics(fn);
}

void printForOneLineLogging(llvm::raw_ostream &os) const {
innerInfo.printForOneLineLogging(os);
void printForCodeDiagnostic(SILFunction *fn, llvm::raw_ostream &os) const {
innerInfo.printForCodeDiagnostic(fn, os);
}
};

} // namespace swift

namespace llvm {

inline llvm::raw_ostream &
operator<<(llvm::raw_ostream &os,
const swift::SILIsolationInfo &isolationInfo) {
isolationInfo.printForOneLineLogging(os);
return os;
}
StringRef printForCodeDiagnostic(SILFunction *fn) const {
return innerInfo.printForCodeDiagnostic(fn);
}

inline llvm::raw_ostream &
operator<<(llvm::raw_ostream &os,
const swift::SILDynamicMergedIsolationInfo &isolationInfo) {
isolationInfo.printForOneLineLogging(os);
return os;
}
void printForOneLineLogging(SILFunction *fn, llvm::raw_ostream &os) const {
innerInfo.printForOneLineLogging(fn, os);
}
};

} // namespace llvm
} // namespace swift

#endif
Loading