Commit Graph

17 Commits

Author SHA1 Message Date
Arnold Schwaighofer
6c0baaee85 Fix closurescope analysis
rdar://50949761
2019-05-20 13:20:23 -07:00
Michael Gottesman
f854547c55 [ownership] Enable ownership verification by default.
I also removed the -verify-sil-ownership flag in favor of a disable flag
-disable-sil-ownership-verifier. I used this on only two tests that still need
work to get them to pass with ownership, but whose problems are well understood,
small corner cases. I am going to fix them in follow on commits. I detail them
below:

1. SILOptimizer/definite_init_inout_super_init.swift. This is a test case where
DI is supposed to error. The only problem is that we crash before we error since
the code emitting by SILGen to trigger this error does not pass ownership
invariants. I have spoken with JoeG about this and he suggested that I fix this
earlier in the compiler. Since we do not run the ownership verifier without
asserts enabled, this should not affect compiler users. Given that it has
triggered DI errors previously I think it is safe to disable ownership here.

2. PrintAsObjC/extensions.swift. In this case, the signature generated by type
lowering for one of the thunks here uses an unsafe +0 return value instead of
doing an autorelease return. The ownership checker rightly flags this leak. This
is going to require either an AST level change or a change to TypeLowering. I
think it is safe to turn this off since it is such a corner case that it was
found by a test that has nothing to do with it.

rdar://43398898
2019-03-25 00:11:52 -07:00
Michael Gottesman
0dfaa19f9f [ownership] Rename enable-sil-ownership => verify-sil-ownership.
I have been meaning to do this change for a minute, but kept on putting it off.
This describes what is actually happening and is a better name for the option.
2019-03-18 01:31:44 -07:00
Michael Gottesman
40a09c9c21 Fixup tests for -assume-parsing-unqualified-ownership-sil => [ossa] transition. 2018-12-18 00:49:32 -08:00
Michael Gottesman
0af0d5fddc [ownership] Replace ValueOwnershipKind::Trivial with ValueOwnershipKind::Any.
In a previous commit, I banned in the verifier any SILValue from producing
ValueOwnershipKind::Any in preparation for this.

This change arises out of discussions in between John, Andy, and I around
ValueOwnershipKind::Trivial. The specific realization was that this ownership
kind was an unnecessary conflation of the a type system idea (triviality) with
an ownership idea (@any, an ownership kind that is compatible with any other
ownership kind at value merge points and can only create). This caused the
ownership model to have to contort to handle the non-payloaded or trivial cases
of non-trivial enums. This is unnecessary if we just eliminate the any case and
in the verifier separately verify that trivial => @any (notice that we do not
verify that @any => trivial).

NOTE: This is technically an NFC intended change since I am just replacing
Trivial with Any. That is why if you look at the tests you will see that I
actually did not need to update anything except removing some @trivial ownership
since @any ownership is represented without writing @any in the parsed sil.

rdar://46294760
2018-12-04 23:01:43 -08:00
Michael Gottesman
c599539044 [sil] Eliminate the src parameter from end_borrow.
This does not eliminate the entrypoints on SILBuilder yet. I want to do this in
two parts so that it is functionally easier to disentangle changing the APIs
above SILBuilder and changing the underlying instruction itself.

rdar://33440767
2018-09-04 16:38:24 -07:00
Andrew Trick
d21f4021bb Enforce exclusivity dynamically in more situations.
A directly applied noescape closure that captures a local requires
dynamic enforcement if that local escaped prior to the direct
application. Previously this was only statically enforced, which could
miss conflicts.

It's unlikely that an actual conflict could occur, but can happen in
cases like this:

func noescapeConflict() {
  var localVal = 0
  let nestedModify = { localVal = 3 }
  _ = {
    takeInoutAndPerform(&localVal, closure: nestedModify)
  }()
}

Code isn't normally written like this, but the general pattern of
passing an escaping closure as an argument to a noescape closure may
arise when using withoutActuallyEscaping. Even in that case, it's
highly unlikely that a real conflict would exist.

For this case to be handled correcly, we must also never allow a
closure passed to withoutActuallyEscaping to be SILGen's as a
non-escaping closure. Doing so would result in a non-escaping closure
to be passed as an argument to the withoutActuallyEscaping trailing
closure, which is also non-escaping. That directly violates the
Non-Escaping Recursion Restriction, but there would be no way to
diagnose the violation, creating a hole in the exclusivity model.
2018-08-17 18:21:20 -07:00
Andrew Trick
d96306fbad Don't run AccessEnforcementSelection on deserialized SIL and add verification.
This is a module pass, so was processing a combination of raw and deserialized
canonical SIL. The analysis makes structural assumptions that only hold prior to
mandatory inlining.

Add more verification of the structural properties.

Teach the pass to skip over canonical SIL, which only works because closures
must be serialized/deserialized in the same module as their parent.

Fixes <rdar://38042781> [Repl] crash while running SILOptimizer
2018-03-02 15:49:01 -08:00
Arnold Schwaighofer
5387bd1732 AccessEnforcementSelection: An @out parameter can be used 2018-02-10 09:29:20 -08:00
Michael Gottesman
9829caff79 [exclusivity] Update tests for ownership.
Some of these did not have ownership at all and some were parsing ownership SIL
with the verifier disabled. Lets just run them with ownership+the verifier.
2017-11-28 21:47:33 -08:00
Andrew Trick
7ceb43fda9 Add support to AccessEnforcementSelection for borrowed SILValues.
Previously, this asserted on unexpected situations that the
optimizer couldn't handle.

It makes more sense now to handle these cases conservatively since we can't
catch them in early testing.

Fixes <rdar://problem/35402799> [4.1] Assertion failed: (user->getResults().empty())
2017-11-13 17:05:20 -08: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
Andrew Trick
fcfabfd5d2 Implement and enable dynamic exclusivity checks for noescape closures.
This uses the new ClosureScopeAnalysis to process parent functions before the
closures they reference. The analysis now tracks captured variables in addition
to immediately accessed variables. If the variable escapes before it's capture
is applied, then that closure uses dynamic enforcement for the variable.

<rdar://problem/32061282> [Exclusivity] Enforcement selection for noescape closure captures.
2017-06-20 00:01:52 -07:00
Andrew Trick
50409b3b1a Make AccessEnforcementSelection a module pass.
Parent scopes need to be analyzed before enforcement in noescape closures can be
selected.
2017-06-16 19:09:24 -07:00
Andrew Trick
dd31c40995 [Exclusivity] Disable dynamic enforcement in noescape closures. 2017-05-08 17:27:26 -07:00
Devin Coughlin
de9c646804 [Exclusivity] Use dynamic enforcement on boxes whose projections escape
In AccessEnforcementSelection, treat passing a projection from a box to
a partial_apply as an escape to force using dynamic enforcement on the box.

This will now correctly use dynamic enforcement on variables that are taken
as inout and also captured by storage address in a closure:

  var x = ...

  x.mutatingMethod { ... use x ...}

but does pessimize some of our existing enforcement into dynamic since
access enforcement selection.

Ideally we would distinguish between escaping via an nonescaping closures
(which can only conflict with accesses that are in progress) and
escaping via escaping closures (which can conflict for any reachable code
after the escape)
2017-05-02 14:54:12 -07:00
Andrew Trick
8ecc3e31cf [Exclusivity] access enforcement SIL tests. 2017-04-28 21:33:09 -07:00