Commit Graph

149 Commits

Author SHA1 Message Date
Michael Gottesman
50712a1666 [region-isolation] Emit a standard short warning + long note when emitting a strongly transferring a structurally isolated value warning.
Specifically, instead of what I call an IsolationRegionInfo + Type error, e.x.:

> task-isolated value of type 'NonSendableType' passed as a strongly transferred parameter; later accesses could race

we use instead the standard warning of:

```swift
func transfer(_ x: transferring Type) {}

func test(_ x: Type) {
  transfer(x) // expected-warning {{transferring 'x' may cause a race}}
  // expected-note @-1 {{task-isolated 'x' is passed as a transferring parameter; Uses in callee may race with later task-isolated uses}}
}
```

Implementation wise, I left in the old type diagnostic as a backup for now. With
time, I am going to want to eliminate it completely.
2024-03-11 19:13:27 -07:00
Michael Gottesman
806cd7940e [region-isolation] Fix actor isolated parameters to get an actor isolated error instead of a task isolated error.
Now that we actually know the region that non transferrable things belong to, we
can use this information to give a better diagnostic here.

A really nice effect of this is that we now emit that actor isolated parameters
are actually actor isolated instead of task isolated.
2024-03-10 22:08:40 -07:00
Michael Gottesman
a5c8106e6a [region-isolation] Standardize on task-isolated instead of task isolated.
This matches actor-isolated as used in other parts of the compiler.
2024-03-10 22:08:40 -07:00
Michael Gottesman
b2c85a8294 [region-isolation] Rather than tracking task isolated values via a separate non-transferrable array... just track it by using ValueIsolationRegionInfo on a value.
In a subsequent commit, this is going to let me begin handling parameters with
actor regions in a nice way (and standardize all of the errors).

This is meant to be a refactoring commit that uses the current tests in tree to
make sure I did it correctly, so no tests need to be updated.
2024-03-10 22:08:40 -07:00
Michael Gottesman
93844934f9 [region-isolation] Begin tracking region information instead of just whether a value is actor derived.
To keep this as an NFC commit, I only modeled initially actor isolated using
this. I am going to make it so that we properly treat global actor isolated
values as actor isolated/etc in a subsequent commit.
2024-03-10 22:08:40 -07:00
Michael Gottesman
f63ac2e16c [region-isolation] Simplify TransferNonTransferrable diagnostic to be like UseAfterTransfer by using an emitter struct.
This makes it easier to debug/maintain/understand the code since the place that
emits the diagnostics is no longer split from the place that decides if a
diagnostic should be emitted. It also lets me eliminate the utility data
structure used to transfer data over.
2024-03-08 12:42:15 -08:00
Michael Gottesman
9bfddfe464 [region-isolation] Simplify the code for use after transfer errors.
Specifically, we previously would generate a list of errors to emit and then
have one centralized piece of code that went through the list and emitted them.
Instead, we now have a low level emitter struct that is just used to emit the
diagnostic at the immediate point where we would create previously an error
record. This places the diagnostic emission next to the piece of code that
triggered it being emitted making it easier to debug why an error was emitted
using -Xllvm -swift-diagnostics-assert-on-*.

I am going to do the same for transfer non transferrable in a little bit once
the async let patch has landed. It has some transfer non transferable error
additions that I want to get in so I am going to wait on that.

NFCI.
2024-03-06 16:47:39 -08:00
Michael Gottesman
f06244f397 [region-isolation] Take into account that Swift's RPO order doesn't include blocks that are dead.
When we run RegionAnalysis, since it uses RPO order, we do not visit dead
blocks. This can create a problem when we emit diagnostics since we may merge in
a value into the region that was never actually defined. In this patch, if we
actually visit the block while performing dataflow, I mark a bit in its state
saying that it was live. Then when we emit diagnostics, I do not visit blocks
that were not marked live.

rdar://124042351
2024-03-04 17:09:51 -08:00
Michael Gottesman
6eb31b42b1 [region-isolation] Assigning into a transferring parameter should be a store, not a transfer.
rdar://123865943
2024-02-29 16:20:00 -08:00
Michael Gottesman
c698f7c5e9 [region-isolation] Use the user facing type rather than the SIL type when emitting a function argument captured by actor isolated closure error. 2024-02-22 19:45:46 -08:00
Michael Gottesman
37bae7af83 [region-isolation] Use the sugared AST type when emitting a TransferNonTransferrable error for passing an argument as a transferrig parameter. 2024-02-22 19:45:46 -08:00
Michael Gottesman
02be75a603 [region-isolation] Emit a better error when a function parameter is assigned into a different transferring parameter.
Just eliminating another "call site passes `self`" error.
2024-02-22 13:50:07 -08:00
Michael Gottesman
8fd70eca94 [region-isolation] Create helpers for inferring name from value and infer name/root from value.
This just cleans up the code by not exposing the details from the
VariableNameInferrer outside of the utilities. It also makes it easier to write
conditional code that uses these helpers by returning an optional, so instead of
having a long setup + an if statement, we just have an if statement optional
check.
2024-02-22 13:50:07 -08:00
Michael Gottesman
7f43c3aa86 [region-isolation] Eliminate "call site passes self" error from all SIL tests. 2024-02-22 13:50:07 -08:00
Michael Gottesman
1c193caedb [region-isolation] Eliminate more "call site passes self" warnings
I just did a full pass through. There were some cases around nonisolated
closures defined in methods and global actor isolated things where we are now
emitting the wrong message. I am going to fix that in subsequent commits.
2024-02-22 13:50:06 -08:00
Michael Gottesman
e4bd7f7dcd [region-isolation] Track the full isolation crossing when emitting transfer non transferrable error.
Preparing for beginning to emit named errors where I need this information. This
just lets me do it before that other commit to make it cleaner.

NFC.
2024-02-22 13:50:06 -08:00
Michael Gottesman
eeba7910b8 [region-isolation] Inline an initForApply call that wasn't really necessary.
Just simplifying code. I also deleted dead code as well.
2024-02-22 13:50:06 -08:00
Michael Gottesman
31baceb6f2 [region-isolation] Reformat transfer non sendable so that utility code is next to the routines that use the utility.
NFC.

Before this commit, the diagnostic emission was split into utilities that were
used by one large emitter class. This could get confusing since there was some
duplication of names in between the utilities. Now instead, each part of the
main diagnostic emitter is in the MARK: section of the utilities that it uses.

Just making the pass easier for me to reason about.
2024-02-22 13:50:06 -08:00
Nate Chandler
6b0fc181d5 [NFC] Removed imports of MemoryLocations.h.
Make it clear that this is only used by the MemoryVerifier (and the
disabled old DestroyHoisting).
2024-02-19 11:41:38 -08:00
Michael Gottesman
40cd98794d [region-isolation] Always require before transferring.
We purposely do not treat a PartitionOpKind::Transfer as a require since that
would cause us to error when we weakly transfer the same parameter multiple
times to the same function. This is safe since all of the function parameters
will be in the same region.

To ensure that this fixed the multiple strong transferring issue (which is
exposed by requiring before transferring), I also had to muck around a little
with how we emit errors to ensure that we emit errors if the transfer
instruction is also the require.
2024-02-14 14:39:02 -08:00
Michael Gottesman
1e4fe6c4ea [region-isolation] Do not transfer @out parameters!
Instead treat them as actual results.
2024-02-06 18:14:34 -08:00
Michael Gottesman
fef1b5e3df [region-isolation] Use VariableNameUtils to emit name diagnostics when possible.
A name diagnostic looks as follows:

Some notes:

1. VariableNameUtils still doesn't pattern match all cases. In the cases where
we fail to pattern match, I fall back to the old diagnostics. I am going to be
adding tests/etc specific to VariableNameUtils in a later patch.

2. I took this as an opportunity to begin preparing to change the diagnostics
into diags of the following form:

a. The main diagnostic is changed to something short "transferring non-Sendable
%0 could yield races with later accesses".

b. I added a longer note at the same location that explains that our caller is
in a specific isolation domain and our callee is isolated differently.

c. I added a note on the definition location of the identified value.
2024-02-06 13:42:35 -08:00
Michael Gottesman
9ff4094b5d [region-isolation] Handle non-transferrable function arguments via an explicitly transferred parameter.
I also while doing this I replaced a bunch of places where we used to crash due
to invariants failing to instead emit a "I don't know error" since it is more
actionable for the user.
2024-01-27 16:16:33 -08:00
Michael Gottesman
d77dede6ce [region-isolation] Change WARNINGS to be ERRORs that are limited as warnings until swift 6.
I added some small infrastructure so that the default way one creates
diagnostics sets this automagically so mistakes cannot result.

rdar://121755281
2024-01-27 16:16:33 -08:00
Michael Gottesman
f077e4a9d7 [region-isolation] Fix the call site or self error for values used in the same region as a function argument.
This is just good to do and also makes it so that in my test case for
assumeIsolated, I get a better msg.
2024-01-25 20:40:56 -08:00
Michael Gottesman
8ff934193b [region-isolation] Move RequireLiveness above the diagnostic emission utilities since I am going to be adding more logic to the diagnostic emission utilities. 2024-01-25 20:40:56 -08:00
Michael Gottesman
48ecf6734f [region-isolation] Hide some state only associated with the UseAfterTransferDiagnostic.
I am doing this since I am going to add something similar albeit
different/specialized for the TransferNonTransferrable diagnostic.
2024-01-25 20:40:56 -08:00
Michael Gottesman
40754ba587 [region-isolation] Begin preparing to cleanup the "call site passes self or argument" warning.
This involves me changing where we emit the error. Instead of us emitting the
error early in the evaluator, we emit it later when we emit diagnostics for all
other transferring things.

This is NFCI.
2024-01-25 20:40:56 -08:00
Michael Gottesman
7c79a24a1f [region-isolation] Values that are captured by an actor isolated closures are transferred to that closure.
This commit makes it so that we treat values captured by an actor isolated
closure as being transferred to that closure. I also introduced a new diagnostic
for these warnings that puts the main warning on the capture point of the value
so the user is able to see the actual capture that causes the transfer to occur:

```swift
  nonisolated func testLocal2() async {
    let l = NonSendableKlass()

    // This is not safe since we use l later.
    self.assumeIsolated { isolatedSelf in
      isolatedSelf.ns = l
    }

    useValue(l) // expected-note {{access here could race}}
  }
```

```
test.swift:74:14: warning: main actor-isolated closure captures value of non-Sendable type 'NonSendableKlass' from nonisolated context; later accesses to value could race
    useValue(x) // expected-warning {{main actor-isolated closure captures value of non-Sendable type 'NonSendableKlass' from nonisolated context; later accesses to value could race}}
             ^
test.swift:76:12: note: access here could race
  useValue(x) // expected-note {{access here could race}}
           ^
```

One thing to keep in mind is that if we have a function argument being captured
in this way, we still emit the "call site passes `self`" error. I am going to
begin cleaning that up in the next commit in this PR so that we emit a better
error here. But it makes sense to split these into two separate commits since
they are doing different things.

rdar://121345525
2024-01-25 20:40:56 -08:00
Michael Gottesman
eb573092d1 [region-isolation] Teach the checker that a use of a local value after being strongly transferred is an error.
Before the previous patch, we were just getting lucky on macOS due to UB. Now
that the UB is fixed, we correctly crash without this commit since we were not
pattern matching the simple case of a local value that was transferred and used
later.
2024-01-18 13:20:28 -08:00
Michael Gottesman
23adcbadb9 [region-isolation] Eliminate some UB caused by dereferencing unchecked optionals.
llvm::Optional<T> used to make it so that in asserts builds if one dereferenced the optional and nothing was there, one would get an assert. std::optional<T> does not have that property.
2024-01-18 13:20:28 -08:00
Michael Gottesman
9303c40162 [region-isolation] Teach region isolation that assigning into a transferring parameter is a transfer of the value.
The specific semantics is if we assign into a transferring parameter's field,
then we "merge" src's value into the transferring parameter, so we
conservatively leave the region of the transferring parameter alone. If we
assign over the entire transferring parameter, we perform an assign fresh since
any value that used to be in the transferring parameter cannot reference
anything in its new value since they are all gone.
2024-01-18 13:20:28 -08:00
Michael Gottesman
053e30d46d [region-isolation] Make sure not to run RegionAnalysis on functions that we do not support.
Before this commit, this was done at the beginning of TransferNonSendable. I
thought that those checks would be sufficient to ensure that
RegionAnalysisFunctionInfo was not created for functions that we do not
support. Turns out when we perform certain forms of verification, we force all
function analyses to be created for all functions meaning that we would create a
RegionAnalysisFunctionInfo for such an unsupported function causing us to hit
asserts.

In this commit, I move the check to whether or not we support a function into
RegionAnalysisFunctionInfo itself and use that to determine if we should run
TransferNonSendable. This additionally allows me to change
RegionAnalysisFunctionInfo so that one can construct one for an unsupported
function... as long as one doesn't actually touch any of its methods. If one
does, I put in an assert so we will know that operator error has occured.
2024-01-10 13:41:12 -08:00
Michael Gottesman
a9dc4ed6cc [region-isolation] Refactor out the Region analysis from TransferNonSendable.
NFCI. This is just a pure refactor of the analysis part of TransferNonSendable
into a separate SIL level analysis so it can be reused by other passes.

The reason that I am committing this earlier is that I am working concurrently
on other patches that change TransferNonSendable itself and I want to avoid
issues when rebasing those patches. Getting this patch into tree earlier avoids
that.

This is in preparation for adding a new flow sensitive initialization pass that
combines region based analysis with the current flow sensitive isolation's
diagnostic emitter. The idea is that we want to preserve the diagnostics from
that pass rather than try to make our own as an initial step.
2024-01-10 13:41:12 -08:00
Michael Gottesman
bee76bf696 [region-isolation] Add support for unchecked_value_cast.
Same as unchecked_trivial_bit_cast.
2023-12-19 16:42:02 -08:00
Michael Gottesman
fbc8b53c8f [region-isolation] Add support for unchecked_bitwise_cast.
Just followed the model of unchecked_trivial_bit_cast.
2023-12-19 15:52:04 -08:00
Michael Gottesman
0b74399768 [region-isolation] Add support for unchecked_trivial_bit_cast
NOTE: This required me to stop using swift::getUnderlyingObject from
getUnderlyingTrackedObject since when it stripsCasts it looks through
unchecked_trivial_bit_cast... but we only want to do that if both the operand
and result of the instruction are non-Sendable. To fix this I inlined
getUnderlyingObject's impl and removed that part of stripCasts.
2023-12-19 15:45:20 -08:00
Michael Gottesman
d08359eb20 [region-isolation] Add support for ref_to_raw_pointer, raw_pointer_to_ref, index_raw_pointer. 2023-12-19 15:21:42 -08:00
Michael Gottesman
c90097f1f0 [region-isolation] Add support for *_existential_box instructions.
NOTE: I am just adding coverage that we support these instructions. One can only
use this with Error today and Error is always Sendable. So this is just going
for completeness.
2023-12-19 13:29:12 -08:00
Michael Gottesman
ddd8c01877 [region-isolation] Do not treat mark_dependence as an ignore. Treat it as an assign from op 0 -> result and a require of op 1.
Semantically a mark_dependence returns a value that is equal to its first
parameter with the extra semantics that any destroys of the 2nd operand cannot
occur before any uses of the result of the instruction. From a region
perspective this suggests that the instruction should be an assign from the
first operand onto the result and act as a require on the result. Semantically
the requirement that the 2nd operand cannot be destroyed before any uses of the
result does not expose any memory or state from the first operand implying that
we don't need to merge it into the result region. The restriction is purely to
tell the optimizer what it can/cannot do rather.
2023-12-18 16:56:32 -08:00
Michael Gottesman
71a8c8eedc [region-isolation] Some small comment cleanups/reordering of definitions. NFCI. 2023-12-18 16:29:46 -08:00
Michael Gottesman
998f067d59 [region-isolation] Add support for mark_unresolved_move_addr. It is a store. 2023-12-18 16:21:34 -08:00
Michael Gottesman
f6cda45e52 [region-isolation] Add support for alloc_vector. Its an assign fresh. 2023-12-18 12:47:42 -08:00
Michael Gottesman
58a6e2aa4d [region-isolation] Add Asserting support for {alloc,dealloc}_pack_metadata since they only appear in Lowered SIL.
I also added a note to the SIL.rst and an assert into the SILVerifier to better
document this requirement.
2023-12-18 12:35:40 -08:00
Michael Gottesman
4a635b61a4 [region-isolation] Add support for fix_lifetime.
fix_lifetime just acts as a require.
2023-12-18 12:35:40 -08:00
Michael Gottesman
59fe82d878 [region-isolation] Do not run on non-Ownership SSA SIL and mark certain instructions that can only appear in non-OSSA as asserting.
We already only supported Ownership SSA since we run early in the pipeline
before OSSA is lowered. This just formalizes this behavior. I am marking these
instructions as Asserting (even though we will never see them) so I can
semantically be sure that all of the instructions are covered without using an
"unsupported" like moniker that I fear will lead to new instructions being added
as unsupported. Better to have a semantic thing for new instruction adders to
use.
2023-12-18 12:35:40 -08:00
Michael Gottesman
7712639ab0 [region-isolation] Add support for project_block_storage.
rdar://119743743
2023-12-18 09:35:57 -08:00
Michael Gottesman
bcb8f1b0d8 [region-isolation] Implement the dataflow correctly.
This involved fixing a few different bugs.

1. We were just performing dataflow by setting that only the initial block needs
to be updated. This means that if there isn’t anything in the initial dataflow
block, we won’t visit any successor blocks. Instead the correct thing to do here
is to visit all blocks in the initial round.

2. I also needed to fix a separate issue where we were updating our union-find
data structure incorrectly as found by an assert on transfernonsendable.swift
that was triggered once I fixed 1. Put simply, we needed to set a new max label
+ 1 when our new max element is less than or equal to the old max label + 1…
before we just did less than so if we had a new max element that is the same as
our fresh label, we wouldn’t increment the fresh label.

rdar://119584497
2023-12-15 17:14:09 -08:00
Michael Gottesman
09151bd800 [region-isolation] Add lookthrough support for a bunch of instructions.
Specifically:

* MoveValueInst
* MarkUnresolvedNonCopyableValueInst
* MarkUnresolvedReferenceBindingInst
* CopyableToMoveOnlyWrapperValueInst
* MoveOnlyWrapperToCopyableValueInst
* MoveOnlyWrapperToCopyableBoxInst
* MoveOnlyWrapperToCopyableAddrInst
* CopyableToMoveOnlyWrapperAddrInst
* MarkUninitializedInst
2023-12-14 19:11:06 -08:00
Michael Gottesman
13d48d2de3 [region-isolation] Add support for explicit_copy_value as a look through instruction. 2023-12-14 19:11:06 -08:00