* add is_escaping_closure as allowed instruction
* don't restrict the uses of copy_value to be a store
Fixes a verification crash (only in assert builds).
https://bugs.swift.org/browse/SR-14394
rdar://75740622
Potentially source breaking: SR-11700 Diagnose exclusivity violations
with Dictionary.subscript._modify:
Exclusivity violations within code that computes the `default`
argument during Dictionary access are now diagnosed.
```swift
struct Container {
static let defaultKey = 0
var dictionary = [defaultKey:0]
mutating func incrementValue(at key: Int) {
dictionary[key, default: dictionary[Container.defaultKey]!] += 1
}
}
error: overlapping accesses to 'self.dictionary', but modification requires exclusive access; consider copying to a local variable
dictionary[key, default: dictionary[Container.defaultKey]!] += 1
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: conflicting access is here
dictionary[key, default: dictionary[Container.defaultKey]!] += 1
~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
```
This reworks the logic so that four problems end up being fixed:
Fixes three problems related to coroutines:
(1) DiagnoseStaticExclusivity must consider begin_apply as a user of accessed variables. This was an undefined behavior hole in the diagnostics.
(2) AccessedSummaryAnalysis should consider begin_apply as a user of accessed arguments. This does not show up in practice because coroutines don't capture things.
(3) AccessedSummaryAnalysis must consider begin_apply a valid user of
noescape closures.
And fixes one problem related to resilience:
(4) AccessedSummaryAnalysis must conservatively consider arguments to external functions.
Fixes <rdar://problem/56378713> Investigate why AccessSummaryAnalysis is crashing
Right now the stdlib/overlays can compile against -Onone tests with or without
-enable-ownership-stripping-after-serialization. This will help me to prevent
other work going on from breaking these properties.
Add support to static diagnostics for tracking noescape closures through block
arguments.
Improve the noescape closure SIL verification logic to match. Cleanup noescape
closure handling in both diagnostics and SIL verification to be more
robust--they must perfectly match each other.
Fixes <rdar://problem/42560459> [Exclusivity] Failure to statically diagnose a
conflict when passing conditional noescape closures.
Initially reported in [SR-8266] Compiler crash when checking exclusivity of
inout alias.
Example:
struct S {
var x: Int
mutating func takeNoescapeClosure(_ f: ()->()) { f() }
mutating func testNoescapePartialApplyPhiUse(z : Bool) {
func f1() {
x = 1 // expected-note {{conflicting access is here}}
}
func f2() {
x = 1 // expected-note {{conflicting access is here}}
}
takeNoescapeClosure(z ? f1 : f2)
// expected-error@-1 2 {{overlapping accesses to 'self', but modification requires exclusive access; consider copying to a local variable}}
}
}
In Swift 4.1 we fixed a false negative and started looking through
reabstraction thunks to statically find exclusivity violations. To lessen
source impact, we treated these violations as warnings. This commit upgrades
those warnings to errors.
rdar://problem/34669400
Update static enforcement to look through noescape blocks to find an underlying
noescape closure when a closure is converted to a block and passed as an
argument to a function. This fixes a false negative when the closure performs
an access that conflicts with an already in-progress access.
These new diagnostics are warnings for source compatibility but will
be upgraded to errors in the future.
rdar://problem/32912660
This fixes a serious false negative in static exclusivity enforcement when
a noescape closure performs an access that conflicts with an in-progress access
but is not reported because the closure is passed via a reabstraction thunk.
When diagnosing at a call site, the enforcement now looks through partial
applies that are passed as noescape arguments. If the partial apply takes
an argument that is itself a noescape partial apply, it recursively checks
the captures for that partial apply for conflicts and diagnoses if it finds one.
This means, for example, that the compiler will now diagnose when there is a
conflict involving a closure with a concrete return type that is passed to a
function that expects a closure returning a generic type. To preserve source
compatibility these diagnostics are emitted as warnings for now. The intent is
that they will be upgraded to errors in a future version of Swift.
rdar://problem/35215926, SR-6103
Update static exclusivity diagnostics to not suggest copying to a local
when a call to swapAt() should be used instead. We already emit a FixIt in
this case, so don't suggest an an helpful fix in the diagnostic.
rdar://problem/32296784
Make the static enforcement of accesses in noescape closures stored-property
sensitive. This will relax the existing enforcement so that the following is
not diagnosed:
struct MyStruct {
var x = X()
var y = Y()
mutating
func foo() {
x.mutatesAndTakesClosure() {
_ = y.read() // no-warning
}
}
}
To do this, update the access summary analysis to summarize accesses to
subpaths of a capture.
rdar://problem/32987932
Make the static enforcement of accesses in noescape closures stored-property
sensitive. This will relax the existing enforcement so that the following is
not diagnosed:
struct MyStruct {
var x = X()
var y = Y()
mutating
func foo() {
x.mutatesAndTakesClosure() {
_ = y.read()
}
}
}
To do this, update the access summary analysis to be stored-property sensitive.
rdar://problem/32987932
Fix an unreachable when constructing the description of the accessed subpath
when diagnosing an exclusivity violation on a variable of
BoundGenericStructType.
rdar://problem/33031311
Use the AccessSummaryAnalysis to statically enforce exclusive access for
noescape closures passed as arguments to functions.
We will now diagnose when a function is passed a noescape closure that begins
an access on capture when that same capture already has a conflicting access
in progress at the time the function is applied.
The interprocedural analysis is not yet stored-property sensitive (unlike the
intraprocedural analysis), so this will report violations on accesses to
separate stored properties of the same struct.
rdar://problem/32020710
Remove the descriptive decl kind (since with subpaths it is not correct and
cannot represent a tuple element) and change "simultaneous" to "overlapping"
in order to lower the register slightly and avoid connoting threading.
For example, for the following:
takesTwoInouts(&x.f, &x.f)
the diagnostic will change from
"simultaneous accesses to var 'x.f', but modification requires exclusive access;
consider copying to a local variable"
to
"overlapping accesses to 'x.f', but modification requires exclusive access;
consider copying to a local variable"
Relax the static enforcement of exclusive access so that we no longer diagnose
on accesses to separate stored structs of the same property:
takesInout(&s.f1, &s.f2) // no-warning
And perform the analogous relaxation for tuple elements.
To do this, track for each begin_access the projection path from that
access and record the read and write-like modifications on a per-subpath
basis.
We still warn if the there are conflicting accesses on subpaths where one is
the prefix of another.
This commit leaves the diagnostic text in a not-so-good shape since we refer
to the DescriptiveDeclKind of the access even describing a subpath.
I'll fix that up in a later commit that changes only diagnostic text.
https://bugs.swift.org/browse/SR-5119
rdar://problem/31909639
This fixes a too-strong assertion when suggesting a Fix-It to replace
module-qualified calls to swap():
Swift.swap(&a[i], &a[j])
Other than weakening the assert, there is no functional change here.
rdar://problem/32358872
Extend the static diagnostics for exclusivity violations to suggest replacing
swap(&collection[index1], &collection[index2]
with
collection.swapAt(index1, index2).
when 'collection' is a MutableCollection.
To do so, repurpose some vestigial code that was previously used to suppress all
exclusivity diagnostics for calls to swap() and add some additional syntactic,
semantic, and textual pattern matching.
rdar://problem/31916085
Update the static diagnostics when enforcing exclusive access to suggest adding
a local variable. The new diagnostic text is:
"simultaneous accesses to var 'a', but modification requires exclusive
access; consider copying to a local variable"
We're now double-diagnosing some things that are caught by both
SILGen and static enforcement; we can fix that later, but I want to
unblock this problem first.
Static diagnostics now refer to the identifier for the variable requiring
exclusive diagnostics. Additionally, when two accesses conflict we now always
emit the main diagnostic on the first modifying access and the note on either
the second modifying access or the read.
The diagnostics also now highlight the source range for the expression
beginning the access.
Add a simple, best-effort static check for exclusive access for stored
class properties. For safety these properties must be checked dynamically,
also -- but we'll now diagnose statically if we see an obvious violation.
Add a SILLocation-based syntactic suppression for diagnostics of static
access conflicts on the arguments to the Standard Library's swap() free
function. We'll suppress for calls to this function until we have a safe
replacement.