Commit Graph

163 Commits

Author SHA1 Message Date
Joe Groff
01405ba2e8 Fixes for compound payloads in borrowing switches.
Fill in a missing path for destructuring loadable elements from
address-only tuples in a borrowing context. Enclose projections in their
own separate accesses so that they are analyzed independently by the
move checker.
2024-02-19 17:37:34 -08:00
Joe Groff
810880c7fa MoveOnlyAddressChecker: Relax more checks to accommodate borrowing switch codegen.
`unchecked_take_enum_data_addr` should not be considered a write when it's non-
destructive; this should eventually be an inherent property of the instruction,
but there are other passes which miscompile currently if we change that now.
Meanwhile, wrapping a copyable value should always be considered an initialization
too.
2024-02-19 09:26:43 -08:00
Nate Chandler
da968dbd58 [MoveChecker] Ban exported partial consumption.
To avoid dialecticization based on compilation mode, ban for
non-resilient modules partial consumption of aggregates which would be
illegal were those modules instead resilient.
2024-02-15 16:25:53 -08:00
Joe Groff
0365c6abba MoveOnlyAddressUtils: Fixes for borrowing switch over address-only types.
Relax some existing pattern matches and add some unhandled instructions to the
walkers so that borrowing switches over address-only enums are properly analyzed
for incorrect consumption. Add a `[strict]` flag to `mark_unresolved_move_only_value`
to indicate a borrow access that should remain a borrow access even if the subject
is later stack-promoted from a box.
2024-02-12 20:20:50 -08:00
Joe Groff
2f519f42c6 SILGen: Emit borrowing switch subjects under a formal access.
Ensure that dependent accesses are properly nested when a subject isn't directly
a borrowed parameter binding.
2024-02-05 19:39:10 -08:00
Nate Chandler
03f904af0c [MoveChecker] Separate partial reinit from consume 2024-01-29 18:29:40 -08:00
Nate Chandler
bff7618353 [MoveChecker] Don't add defs to liveness.
When extending liveness, the instructions prior to a preexisting destroy
are added to liveness.  If that prior instruction is the def, adding it
to liveness results in multi-def liveness understanding that there is a
prior def.

Fixes a bug exposed by adding coroutine ends to liveness rather than
function ends.
2024-01-29 12:31:25 -08:00
Nate Chandler
c06d5dbb0b [MoveChecker] All assigns add the same scope ends.
Use the same code path to add users at which an address must have been
reinitialized for both kinds of mark_unresolved_non_copyable_value which
permit assignment.
2024-01-29 11:49:30 -08:00
Nate Chandler
5441ff1d97 [MoveChecker] Distinguished scope end diagnostics.
There are several kinds of scopes at which it is required that an
address be initialized:
(1) the whole function -- for inout argument to the function
(2) the region a coroutine is active -- for an inout yielded by a
    coroutine into the function
(3) the region of a memory access -- for a `begin_access [modify]`.

The move checker enforces that they are initialized at that point by
adding instructions at which the field must be live to liveness.

Previously, all such scopes used the end of the function as the point at
which the memory had to have been reinitialized.  Here, the relevant end
of scope markers are used instead.

More importantly, here the diagnostic is made to vary--the diagnostic,
that is, that is issued in the face an address not being initialized at
the end of these different kind of scopes.
2024-01-29 11:49:30 -08:00
Nate Chandler
4ea2440bfe [NFC] MoveChecker: Merged partial mutation checks.
Simplified diagnostic emission to use a single code path.
2024-01-29 11:49:30 -08:00
Nate Chandler
5f3d2938d7 [NFC] MoveChecker: Inverted control flow.
Exited early.
2024-01-29 11:49:30 -08:00
Nate Chandler
b757b2e99d [FSPrunedLiveness] Return bitfield from isDefBlock 2024-01-29 11:49:30 -08:00
Nate Chandler
330f300c4b [NFC] FSPrunedLiveness: Deduplicated initDef impls
Add a new SILNode taking overload and change the SILInstruction and
SILValue taking overloads to call it.
2024-01-29 11:49:29 -08:00
Nate Chandler
e8364d632c [Gardening] MoveChecker: Tweaked comment. 2024-01-25 11:01:14 -08:00
Joe Groff
1b9a0712bf Move-only check the value projected from addressors.
Mark the result of a move-only addressor as unresolved. The pointed-at value
cannot be consumed so ensure that only [read] or [modify] accesses are
performed. Update the move-only checker to recognize code patterns
from addressors.
2023-12-15 10:10:44 -08:00
Joe Groff
18e31157fd Move-only-check the result of modify coroutines.
Following https://github.com/apple/swift/pull/70333, do the same thing for
modify coroutines, marking the result so that we check uses of the result to
ensure it isn't consumed (without being reinitialized).
2023-12-12 09:02:24 -08:00
Joe Groff
96c87dbf81 Move-only-check the yielded result from read coroutines when they're noncopyable.
Mark the result of starting a read coroutine to be checked by the move-only checker, and then
update the pattern matching in the move checker itself so that it recognizes code patterns
involving yielding from and receiving yields from read coroutines. Teach move only diagnostics
to get the property name for an access through a read coroutine from the referenced declaration.
2023-12-11 10:54:52 -08:00
Joe Groff
f126b714bf MoveOnlyChecker: Properly insert cleanup for dead try_apply def.
When a address-only noncopyable value is dead-def'ed by an indirect return from a `try_apply`,
the cleanup should be inserted on the normal return successor block. Fixes rdar://118255228.
2023-11-15 08:42:07 -08:00
Andrew Trick
43e88fd0f1 Fix MoveOnlyTypeChecker to handle address taking instructions
address_to_pointer and fix_lifetime
2023-10-30 12:22:26 -07:00
swift-ci
7fc36edb98 Merge remote-tracking branch 'origin/main' into rebranch 2023-09-27 09:34:12 -07:00
Nate Chandler
05bec97203 [FSPrunedLiveness] Add extendToNonUse.
And use it in lifetime maximization.

The preexisting member function updateForUse has been updated to match
PrunedLiveness and gravitate towards lifetimeEnding=false.

For a fixed instruction and bit, if called with lifetimeEnding=true and
then lifetimeEnding=false, the lifetime-ending-ness of the instruction
at the bit will be false; and if it is again called with
lifetimeEnding=true, the lifetime-ending-ness of the instruction at the
bit will remain false.

In contrast the new member function extendToUse does not alter the
lifetime-ending-ness if it is already set.  If it is unset, the function
sets the bit to lifetimeEnding=false.
2023-09-26 11:45:23 -07:00
Sophia Poirier
86d368f364 Merge remote-tracking branch 'upstream/main' into fix-rebranch-automerger 2023-08-31 14:10:52 -07:00
Michael Gottesman
37d60a08bb [move-only] Rename mark_must_check -> mark_unresolved_non_copyable_value.
I was originally hoping to reuse mark_must_check for multiple types of checkers.
In practice, this is not what happened... so giving it a name specifically to do
with non copyable types makes more sense and makes the code clearer.

Just a pure rename.
2023-08-30 22:29:30 -07:00
swift-ci
d35a7743ef Merge remote-tracking branch 'origin/main' into rebranch 2023-08-29 00:15:35 -07:00
Michael Gottesman
18ac69d8d7 Remove a clang optimize off that snuck into tree. 2023-08-28 18:40:30 -07:00
swift-ci
4fe55c5732 Merge remote-tracking branch 'origin/main' into rebranch 2023-08-11 00:35:20 -07:00
swift-ci
2667df0799 Merge pull request #67760 from atrick/fix-closure-moveonly-arg
Fix compiler crashes with consuming and borrowing keywords.
2023-08-11 00:32:41 -07:00
swift-ci
525350af1b Merge remote-tracking branch 'origin/main' into rebranch 2023-08-10 22:14:25 -07:00
Michael Gottesman
29350907fc Convert TransitiveAddressWalker to use CRTP instead of virtual functions. 2023-08-10 12:58:50 -07:00
Andrew Trick
83ce3a1777 Rename getArgumentOperandConvention to getCaptureConvention
The name was misleading and problematic. There is already a
getArgumentConvention which is completely different.
2023-08-10 11:17:53 -07:00
Becca Royal-Gordon
3eebc6dddb Merge branch 'main' into rebranch
# Conflicts:
#	lib/SILOptimizer/Differentiation/Common.cpp
2023-08-04 15:09:50 -07:00
Michael Gottesman
c9be4bda49 Merge pull request #67677 from gottesmm/borrowed-base-silgenlvalue
[move-only] Ensure that we properly nest accesses to base values if the base is noncopyable or the accessor result is noncopyable.
2023-08-04 12:26:19 -07:00
Michael Gottesman
c3d2276241 [silgen] Eliminate two more cases around subscripts where we were not borrowing.
Also, the store_borrow work in the previous patch caused some additional issues
to crop up. I fixed them in this PR and added some tests in the process.
2023-08-02 11:09:31 -07:00
swift-ci
2919af9fa7 Merge remote-tracking branch 'origin/main' into rebranch 2023-08-01 13:36:46 -07:00
Joe Groff
9b783560ad Fix @_rawLayout initialization to avoid spurious lifetime ends.
We can't really treat them as always-initialized because that makes move checking
think that there's a value to destroy even on initialization, causing deinits to
run on uninitialized memory. Remove my previous hack, and use a `zeroInitializer`
to initialize the value state when emitting `init`, which is where we really need
the bootstrapping-into-initialized behavior. rdar://113057256
2023-08-01 08:34:02 -07:00
Michael Gottesman
55892ef30d [silgen] Add a special visitor for accessing the base of noncopyable types.
We want these to be borrowed in most cases and to create an appropriate onion
wrapping. Since we are doing this in more cases now, we fix a bunch of cases
where we used to be forced to insert a copy since a coroutine or access would
end too early.
2023-07-27 10:00:28 -07:00
swift-ci
1969199a8e Merge remote-tracking branch 'origin/main' into rebranch 2023-07-26 23:13:08 -07:00
Evan Wilde
309aed4925 Add SmallSetVector replacement
llvm::SmallSetVector changed semantics
(https://reviews.llvm.org/D152497) resulting in build failures in Swift.
The old semantics allowed usage of types that did not have an
`operator==` because `SmallDenseSet` uses `DenseSetInfo<T>::isEqual` to
determine equality. The new implementation switched to using
`std::find`, which internally uses `operator==`. This type is used
pretty frequently with `swift::Type`, which intentionally deletes
`operator==` as it is not the canonical type and therefore cannot be
compared in normal circumstances.

This patch adds a new type-alias to the Swift namespace that provides
the old semantic behavior for `SmallSetVector`. I've also gone through
and replaced usages of `llvm::SmallSetVector` with the
`Swift::SmallSetVector` in places where we're storing a type that
doesn't implement or explicitly deletes `operator==`. The changes to
`llvm::SmallSetVector` should improve compile-time performance, so I
left the `llvm::SmallSetVector` where possible.
2023-07-25 12:28:27 -07:00
Joe Groff
aee071bf4e Introduce an experimental @_rawLayout attribute.
This attribute can be attached to a noncopyable struct to specify that its
storage is raw, meaning the type definition is (with some limitations)
able to do as it pleases with the storage. This provides a basis for
implementing types for things like atomics, locks, and data structures
that use inline storage to store conditionally-initialized values.
The example in `test/Prototypes/UnfairLock.swift` demonstrates the use
of a raw layout type to wrap Darwin's `os_unfair_lock` APIs, allowing
a lock value to be stored inside of classes or other types without
needing a separate allocation, and using the borrow model to enforce
safe access to lock-guarded storage.
2023-07-24 14:28:19 -07:00
Michael Gottesman
7aea9d44c3 Merge pull request #67414 from gottesmm/rdar112555589-112547982
[move-only] Fix two small errors around handling capturing of noncopyable self by local functions
2023-07-19 21:28:09 -07:00
Michael Gottesman
b060e5ba60 [move-only] Make sure we mark local function inout parameters with mark_must_check.
Originally, we were relying on capture info to determine if we needed to insert
this mark_must_check. This ignored that the way that we are handling
escaping/non-escaping is something that is approximated in the AST but actually
determined at SIL level. With that in mind, rather than relying on the capture
info here, just rely on us having an inout argument. The later SIL level
checking for inout escapes is able to handle mark_must_check and knows how to
turn off noncopyable errors in the closure where we detect the error to prevent
us from emitting further errors due to the mark_must_check here.

I discovered this while playing with the previous commit.

rdar://112555589
2023-07-19 15:02:04 -07:00
Michael Gottesman
2abfa25bd4 Merge pull request #67354 from gottesmm/pr-45bdcac91308a0aa164064d4356f91a367ea00fa
[move-only] Fix lazily initialized global initializers.
2023-07-18 16:38:36 -07:00
Michael Gottesman
1f22f92170 [move-only] Fix lazily initialized global initializers.
Without this, we emit a copy of noncopyable type error since we do not insert a
mark_must_check on lazily initialized global initializers.

rdar://111402912
2023-07-17 19:17:43 -07:00
Michael Gottesman
d7d7ab6ae2 [move-only] Make sure that we mask out liveness bits and use |= when merging successors
Both of these can cause us to insert destroy_addr in the wrong locations.

1. The first causes us to insert destroys for parts of values that are not
actually on the boundary since we didn't use our mask and instead used all of
the liveness information.

2. We were merging successor information using '&=' instead of '|=. This caused
a problem if we had multiple regions for the same successor. In such a case, we
would not have anything in common for the regions causing us to not have any
bits in common, resulting in us inserting too many destroy_addr instead of
skipping as we were supposed to.

rdar://112434492
2023-07-17 16:10:43 -07:00
Michael Gottesman
69a03c93f9 [move-only] Ban partial reinitialization after consuming a value.
This is similar to our ban on partial consuming a value for this release. The
reason for this is that, one can achieve a similar affect as partial consumption
via a consumption of the entire value and then a partial reinitialization. Example:

```swift
struct X : ~Copyable { var i = 5, var i2 = Klass() }
var x = X()
_ = consume x
x.i = 5
```

in the case above, we now have a value that is in a partially initialized state.

We still allow for move only types to have their fields initialized as long as
there is an intervening init.

rdar://111498740
2023-07-05 20:26:26 -07:00
Michael Gottesman
7e582b0221 [move-only] Split error emission code from testing code. 2023-07-05 18:41:27 -07:00
Michael Gottesman
7028381fe1 [move-only] When adding implicit liveness uses for class field/global accesses, do not use the terminator, use the end access.
Previously, when doing this I could just use the terminator both in cases of
inout and for class field/global accesses... but after some recent changes to
field sensitive pruned liveness, this seems to no longer work. So just do the
right thing and use the field access.

The specific bug was that we would introduce a destroy_addr along one of the
paths where the value wasn't defined resulting in a dominance error.

I added a SIL test that shows this fixes the issue, a swift test, and also an
Interpreter test that validates the correctness.

rdar://111659649
2023-07-03 15:53:51 -07:00
Michael Gottesman
fb487bf0ef [move-only] Improve logging to make it more readable and add a counter to bisect on variables that we are checking.
These are only on in NDEBUG mode. It just makes it easier to quickly triage
which variable is causing a checking problem.
2023-07-03 15:49:41 -07:00
Michael Gottesman
4591e39d02 [move-only] Fix borrowing address only no consume diagnostic to not say can't capture.
We previously were emitting a consuming partial_apply diagnostic. I had to
reformulate slightly the way we pattern match the diagnostics to make sure that
we get the proper no consume diagnostic.

rdar://111461837
2023-06-28 11:20:27 -07:00
Michael Gottesman
bd90e310e1 Merge pull request #66952 from gottesmm/pr-87fcc78991b465d8a15454dc76b66d6f347ddff0
[move-only] Emit an error if we /ever/ partially consume a noncopyable type.
2023-06-28 01:00:40 -07:00