Commit Graph

104 Commits

Author SHA1 Message Date
Andrew Trick
9fdba965b1 [NFC] Create an AccessedStorage utility for use in multiple exclusivity related passes.
Added new files, MemAccessUtils.h and MemAccessUtils.cpp to house the
new utility. Three functions previously in InstructionUtils.h move
here:
- findAccessedAddressBase
- isPossibleFormalAccessBase
- visitAccessedAddress

Rather than working with SILValues, these routines now work with the
AccessedStorage abstraction. This allows enforcement logic and SIL
pattern recognition to be shared across diagnostics and
optimization. (It's very important for this to be consistent).

The new AccessedStorage utility is a superset of the class that was
local to DiagnoseStaticExclusivity. It exposes the full set of all
recognized kinds of storage. It also represents function arguments as
an index rather that a SILValue. This allows an analysis pass to
compare/merge AccessedStorage results from multiple callee functions,
or more naturally propagate from callee to caller context.
2018-04-13 23:07:20 -07:00
Andrew Trick
00df6b1b58 Remove some extraneous logic from -enable-verify-exclusivity.
Once the dust settled, this logic was only protecting a single occurrence of
memory access in SILGenLValue.cpp. It's simpler just to emit the begin/end
access markers in that case. The logic to work around it was nasty.
2018-04-12 22:09:28 -07:00
Devin Coughlin
cef3139d03 [Exclusivity] Treat warning violations with reabstraction thunks as errors
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
2018-04-12 21:38:48 -07:00
Slava Pestov
76349a0f87 Squash some unused variable warnings 2018-03-08 17:05:59 -07:00
Sho Ikeda
26d650292f [gardening] Use empty() over size() == 0 2018-03-05 14:43:13 +09:00
Andrew Trick
8a8c86a21f Exhaustive access marker verification. 2018-02-15 11:26:54 -08:00
Andrew Trick
d8e3a8794e Don't rerun DiagnoseStaticExclusivity on deserialized SIL. 2018-02-15 11:26:54 -08:00
Arnold Schwaighofer
72018934b3 DiagnoseStaticExlusivity: Need to look through convert_escape_to_noescape 2018-02-13 04:19:59 -08:00
Michael Gottesman
988d4095dd [+0-all-args] When diagnosing closure escapes, look through sil borrows.
I also added an option called sil-assert-on-exclusivity-failure that causes the
optimizer to assert if an exclusivity failure is hit. This enables quicker
debugging of exclusivity violations since at the assertion point, you drop
straight down into the debugger. This is only enabled with asserts.

rdar://34222540
2018-02-06 20:44:54 -08:00
Mark Lacey
b4b66bc8e8 Replace getAnyOptionalObjectType with getOptionalObjectType. 2018-02-05 23:59:00 -08:00
Andrew Trick
54ebeb9f67 Exclusivity: handle optional noescape blocks.
Fixes <rdar://36989789> [SR-6862]: "Unexpected partial_apply use" in SILOptimizer/Mandatory/DiagnoseStaticExclusivity.cpp.
2018-02-05 18:43:30 -08:00
Andrew Trick
113bebb035 Centralize logic for access marker and exclusivity verification.
Create helpers in InstructionUtils.h wherever we need a guarantee that the diagnostics cover the same patterns as the verifier. Eventually this will be called from both SILVerifier and the diagnostic pass:
- findAccessedAddressBase
- isPossibleFormalAccessBase
- isPartialApplyOfReabstractionThunk
- findClosureForAppliedArg
- visitAccessedAddress

Add partial_apply verification assert.

This applies the normal "find a closure" logic inside the "find all partial_apply uses" verification. Making the verifier round-trip ensures that we don't have holes in exclusivity enforcement related to this logic.
2018-02-05 18:43:30 -08:00
Andrew Trick
fb42d85dc3 Verify @inout_aliasable captures.
This is currently only done in DiagnoseStaticExclusivity because AllocBoxToStack
doesn't know how to set @noescape function types yet.
2018-01-15 13:46:02 -08:00
Devin Coughlin
88232d6e3b [Exclusivity] Look through block arguments to find noescape closures (#13497)
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
2017-12-19 13:38:09 -08:00
Devin Coughlin
cf9a09e18d [Exclusivity] Diagnose when noescape closure is passed via reabstraction thunk
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
2017-11-16 16:01:08 -08:00
John McCall
aff457381c Change ApplyInstBase to not try to handle trailing objects itself. NFC.
The goal is to make it more composable to add trailing-objects fields in
a subclass.

While I was doing this, I noticed that the apply instructions provided
redundant getNumArguments() and getNumCallArguments() accessors, so I
went ahead and unified them.
2017-11-13 04:03:21 -05:00
John McCall
ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00
Devin Coughlin
6dcc8ce9b2 [Exclusivity] Don't suggest copying to a local when swapAt() is appropriate
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
2017-07-16 13:48:52 -07:00
Devin Coughlin
47d9de9751 [Exclusivity] Relax closure enforcement on separate stored properties (#10789)
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
2017-07-10 13:33:22 -07:00
Devin Coughlin
2501dd71de Revert "[Exclusivity] Relax closure enforcement on separate stored properties" 2017-07-05 20:19:50 -07:00
Devin Coughlin
86dff5c0a7 [Exclusivity] Relax closure enforcement on separate stored properties
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
2017-07-05 16:09:54 -07:00
Devin Coughlin
2eef7cd470 [Exclusivity] Fix unreachable when diagnosing on BoundGenericStructType
Fix an unreachable when constructing the description of the accessed subpath
when diagnosing an exclusivity violation on a variable of
BoundGenericStructType.

rdar://problem/33031311
2017-06-28 12:09:46 -04:00
Andrew Trick
c2c55eea12 AccessSummaryAnalysis: handle @convention(block) in nested nonescape closures.
This analysis has a whitelist to ensure that we aren't missing any SIL
patterns and failing to enforce some cases.

There is a special case involving nested non-escaping closures being passed as a
block argument.  Whitelist this very special case even though we don't enforce
it because the corresponding diagnostics pass also doesn't enforce it.
2017-06-21 19:39:12 -07:00
Devin Coughlin
5ec0563c16 [Exclusivity] Statically enforce exclusive access in noescape closures (#10310)
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
2017-06-17 22:52:29 +01:00
Devin Coughlin
06b9ed7501 [Exclusivity] Switch static checking to use IndexTrie instead of ProjectionPath
IndexTrie is a more light-weight representation and it works well in this case.
This requires recovering the represented sequence from an IndexTrieNode, so
also add a getParent() method.
2017-06-15 18:37:23 -07:00
Devin Coughlin
f6df5c79b2 [Exclusivity] Update static diagnostic text for "simultaneous" accesses
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"
2017-06-13 20:08:48 -07:00
Devin Coughlin
d76ec6a8ff [Exclusivity] Relax enforcement for separate struct stored properties
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
2017-06-13 19:15:38 -07:00
Devin Coughlin
480222c36e [Exclusivity] Make helper functions to static. NFC.
Make helper functions static and avoid defining one except when assertions
are enabled.
2017-06-13 17:00:25 -07:00
Alex Hoppen
faa1720c48 [Diagnostics] Adjustments for DeclBaseName
Adjust the definition of some diagnostics that are already called with
DeclBaseNames so that the implicit conversion from DeclBaseName to
Identifier is no longer needed.

Adjust the call side of diagnostics which don't have to deal with
special names to pass an Identifier to the diagnostic.
2017-05-31 15:58:46 +02:00
Alex Hoppen
8946015d5a [SIL] Preparations for removal of getName on ValueDecl
With the introduction of special decl names, `Identifier getName()` on
`ValueDecl` will be removed and pushed down to nominal declarations
whose name is guaranteed not to be special. Prepare for this by calling
to `DeclBaseName getBaseName()` instead where appropriate.
2017-05-28 19:13:24 -07:00
Devin Coughlin
8974392a56 [Exclusivity] Weaken assert when suggesting swap() Fix-It
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
2017-05-23 20:07:24 -07:00
Devin Coughlin
f239ae2ad7 [Exclusivity] Suggest Fix-Its to replace swap() with swapAt()
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
2017-05-17 17:48:58 -07:00
Andrew Trick
94ad1403e2 [Exclusivity] Check that accesses are well-formed during diagnostics.
This whitelists all the operations that produce an address that
may be accessed and adds SIL test cases.
2017-05-16 10:22:49 -07:00
Andrew Trick
7c34295c16 Add some tracing to debug DiagnoseStaticExclusivity. 2017-05-16 10:22:49 -07:00
Andrew Trick
886b1f869c Revert "[Exclusivity] Check that accesses are well-formed during diagnostics." 2017-05-15 09:53:59 -07:00
Andrew Trick
f78a2ab2d8 [Exclusivity] Check that accesses are well-formed during diagnostics.
This can help catch assumptions in current implementation during testing.
It does not need to be merged to 4.0.
2017-05-11 14:17:35 -07:00
Devin Coughlin
0777cccb71 [Exclusivity] Make static access conflict an error in Swift 4 mode.
When static enforcement of exclusive access is enabled, make access conflicts an
error in Swift 4 mode. They will remain a warning in Swift 3 mode.
2017-05-06 19:13:53 -07:00
practicalswift
ff827e0455 [gardening] Fix recently introduced typos 2017-04-25 21:03:44 +02:00
practicalswift
861f70e13d [gardening] Use consistent spacing 2017-04-25 21:03:43 +02:00
Devin Coughlin
9cdff5fe00 [Exclusivity] Improve static enforcement diagnostics
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.
2017-04-23 11:39:25 -07:00
Devin Coughlin
77611e6ef9 [Exclusivity] Add best-effort static checking for class stored properties.
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.
2017-04-20 14:27:09 -07:00
Devin Coughlin
5d59fbc760 [Exclusivity] Teach static enforcement to look through mark_uninitialized
This will be needed to improve the diagnostic text to refer to the variable
accessed.
2017-04-19 18:18:49 -07:00
Devin Coughlin
ae3b13ed2d [Exclusivity] Put suppression for free function swap() behind a flag
And leave suppression off by default for now. We'll use this to evaluate
how often swap() causes exclusivity conflicts to be reported.
2017-04-18 17:21:53 -07:00
practicalswift
7eb7d5b109 [gardening] Fix 100 typos. 2017-04-18 17:01:42 +02:00
Michael Gottesman
3f6c4b96bb [gardening] Some small llvm style cleanups in DiagnoseStaticExclusivity. 2017-04-16 16:49:33 -07:00
Devin Coughlin
8d180f4bdc [SILDiagnostics] Add suppression for swap() to static access enforcement.
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.
2017-04-15 14:00:38 -07:00
Devin Coughlin
8aa9b3af89 [SILDiagnostics] Move static enforcement enablement early return earlier.
This avoids computing the PostOrderAnalysis when this pass won't use it
because static checks are disabled.
2017-04-15 11:14:59 -07:00
practicalswift
6828ed9e1e [gardening] Use isa<T>(o) instead of dyn_cast<T>(o) when result is unused 2017-04-14 17:33:24 +02:00
practicalswift
d8d1693814 [gardening] Remove unused variables 2017-04-14 17:33:24 +02:00
swift-ci
7e044743a8 Merge pull request #8716 from devincoughlin/exclusive-access-rehash-crasher 2017-04-11 19:43:49 -07:00