Commit Graph

30 Commits

Author SHA1 Message Date
Andrew Trick
305d75187a LocalVariableUtils: precisely handle function live-out
Only record an outgoingArgument access when the current allocation is an
outgoing argument and the function exiting instruction is ReturnInst.

This avoids invalid SIL where we attempt to extend end_access up to an `unwind` but
fail to actually materialize that end_access.
2025-10-23 23:34:26 -07:00
Andrew Trick
62b04caaa7 LocalVariableUtils add non-escaping closure capture support
Don't always consider an inout_aliasable argument to have
escaped. AccessEnforcementSelection has already done that analysis and left
begin_access [dynamic] artifacts if the argument has escaped in any meaningful
way. Use that information to

Essential for supporting autoclosures that call mutating methods on span-like
things. Such as UTF8Span.UnicodeScalarIterator.skipForward():

e.g. while numSkipped < n && skipForward() != 0 { ... }
2025-10-23 23:34:25 -07:00
Andrew Trick
77ee27a0e7 [NFC] LocalVariableAccessInfo.description 2025-10-23 23:34:25 -07:00
Andrew Trick
de34abe3e5 Fix LocalVariableReachableAccess to handle potential reassignment.
Define LocalAccessInfo._isFullyAssigned to mean that the access does not read
the incoming value. Then treat any assignment that isn't full as a potential read.
2025-10-23 23:34:25 -07:00
Andrew Trick
6e0eeb00e3 Fix LifetimeDependenceDefUseWalker for @inout reassignment 2025-10-23 23:34:24 -07:00
Andrew Trick
ff4d053a44 [NFC] LifetimeDependenceDefUseWalker.inoutDependence entry point
Handle cases where there's no relevant operand.
2025-10-23 23:34:24 -07:00
Andrew Trick
239255b8bc Improve LocalVariableUtils.gatherKnownLifetimeUses; dead ends
Add a fake use for dead-end blocks. This allows gatherKnownLifetimeUses to be
used for local liveness by considering an "unreachable" instruction to generate
liveness. This is important when liveness is used as a boundary within which
access scopes may be extended. Otherwise, we are unable to extend access scopes
into dead-end blocks.

Fixes rdar://154406790 (Lifetime-dependent variable 'X' escapes its
scope but only if actor/class is final)
2025-07-03 21:30:37 -07:00
Andrew Trick
fe9c0dd735 Fix LocalVariableUtils switch_enum_addr.
switch_enum_addr was being treated like a store instruction, which killed
the local enum's liveness. This could result local variable analysis reporting a
shorter lifetime for the local.

This showed up as a missing exclusivity diagnostic because an access scope was
not fully extended across a dependent local variable of Optional type.

This prevents the following pattern from miscompiling. It should report an exclusivity violation:

  var mutableView = getOpaqueOptionalView(holder: &holder)!
  mutate(&holder)
  mutableView.modify()

Fixes rdar://151231236 ([~Escapable] Missing 'overlapping acceses' error when
called from client code, but exact same code produces error in same module)
2025-06-28 09:30:17 -07:00
Valeriy Van
949c2bad67 Fix some typos in SwiftCompilerSources/Sources 2025-06-08 11:22:45 +03:00
Andrew Trick
3b08592ed2 Fix LifetimeDependenceDiagnostics: handle drop_deinit unsafeAddress
This adds support to handle unsafe addressors, which generate mark_dependence
instructions with an address base. This case does not arise with lifetime
dependencies. Nonetheless, the lifetime dependence diagnostics kick in to
attempt to promote the unsafe addressor's mark_dependence to noescape, so we
need to handle it.

rdar://149784450 (Compiler crash with non-escapable deinit dereferencing)
2025-04-22 22:35:09 -07:00
Andrew Trick
4e35d255ad LocalVariableUtils: add store_borrow access tracking.
We sometimes use LocalVariableUtils to analyze temporary storage in which the
store_borrow is not already enclosed by an access scope.
2025-04-16 16:46:38 -07:00
Andrew Trick
c9279d9899 Fix AddressOwnershipLiveRange to include the full range.
This allows further extension of access scopes.

Fixes rdar://143992296 (Use of `RawSpan` in switch context causes compiler crash
in AddressOwnershipLiveRange)
2025-04-11 23:49:07 -07:00
Andrew Trick
ccb26bcd89 LocalVariableUtils: add unit tests 2025-04-10 23:27:55 -07:00
Andrew Trick
37ecd0e9bd LocalVariableUtils: fix data flow propagation of escapes.
This is only used for lifetime dependence diagnostics.

Fix a couple of obvious problems with data flow propagation that crept in during
"cleanup" because no unit tests existed.
2025-04-10 23:27:55 -07:00
Andrew Trick
69b6b1d309 LifetimeDependenceDefUseWalker: handle addressable dependencies 2025-03-25 23:02:45 -07:00
Andrew Trick
d9dd93560d Support mark_dependence_addr in SIL passes. 2025-03-25 23:02:45 -07:00
Andrew Trick
8b39b6d16a LocalVariableUtils: record mark_dependence bad address operands
Avoid bailing out when something depends on the local variable.
2025-02-10 09:11:22 -08:00
Andrew Trick
cc07b4ba11 Fix LifetimeDependenceDiagnostics for @out dependencies.
Record a forwarding mark_dependence as a local access. This is necessary because
we now emit a mark_dependence for @out arguments, which will be the starting
point for diagnostics:

  %out = alloc_stack
  apply %f(%owned, %out) : $(Owner) -> @lifetime(borrow 0) @out View
  %unused = mark_dependence [unresolved] %out on %owner
  %dependentValue = load %out

This mark_dependence has no uses. Instead, it simply records the dependency of
the in-memory value on the owner. Consequently, simply walking the uses of
LifetimeDependence.dependentValue does fails to diagnose any escapes. Instead,
if the dependentValue is an address-type mark_dependence, treat it as a local
access to the address that it forwards. Then we find any reachable uses of that
local variable as a potential escape.

Fixes rdar://143040479
(Borrow diagnostics not triggered for @out return values)
2025-01-17 11:19:04 -08:00
Andrew Trick
afda6453a5 Improve LocalVariableAccessInfo: recognize more full-assignments.
Ignore marker instructions for the purpose of determining whether a store is a
full assignment:

  %a = alloc_stack
  %m = moveonlywrapper_to_copyable_addr %a
  store %0 to [init] %m // <=== full assignemt
2025-01-17 11:19:04 -08:00
Erik Eckstein
701a7f7275 SwiftCompilerSources: don't make anything public in the Optimizer module
The Optimizer module is a leave module. No other modules depend on it. Therefore nothing must be public in this module.
2024-10-02 07:10:28 +02:00
Andrew Trick
e4036b970b Improve LocalVariableAccessWalker to handle switch_enum_addr. 2024-08-19 18:01:49 -07:00
Alexander Cyon
c18a24e499 [SwiftCompilerSources] Fix typos 2024-08-08 22:22:39 -07:00
Andrew Trick
11ba799cd4 LifetimeDependence: diagnose yield and store-to-yield. 2024-07-30 16:27:48 -07:00
Andrew Trick
c41dc33c10 LocalVariableUtils: handle projections inside initializers.
These projections don't have access scopes, so the utility was treating them
like escapes.

Fixes: rdar://131499478 (Difficulties composing non-escapable types)
2024-07-12 19:58:14 -07:00
Andrew Trick
fc60925a38 LocalVariableUtils: add support for temporary enum initialization. 2024-04-12 14:11:37 -07:00
Andrew Trick
e77fff3d23 LocalVariableUtils logging 2024-03-18 17:45:33 -07:00
Andrew Trick
f1fbbcd438 Handle escaping addresses in LocalVariableAccessWalker
Fixes rdar://124564951 (Compiler crash when evaluating pointer escape
in autoclosure; LifetimeDepenenceScopeFixup; Fatal error: check
findPointerEscape() before computing interior liveness.)
2024-03-18 17:45:33 -07:00
Andrew Trick
00fbf4f1af LocalVariableUtils logging 2024-03-18 17:45:33 -07:00
Andrew Trick
aa208bbf91 Add SILType::containsNoEscapeFunction()
Add PartialApplyInst.hasNoescapeCapture
Add PartialApplyInst.mayEscape

Refactor DiagnoseInvalidEscapingCaptures. This may change functionality because tuples containing a noescape closure are now correctly recognized. Although I'm not sure such tupes can ever be captured directly.
2024-03-18 17:38:12 -07:00
Andrew Trick
ffe9c48976 Add LocalVariableUtils
This includes a reaching-def analysis that can be used by diagnostic passes. Diagnostics should be flow-sensitive.
2024-03-05 18:08:16 -08:00