Commit Graph

405 Commits

Author SHA1 Message Date
Andrew Trick
ed158ffdcb [NFC] LifetimeDependence computeAddressRange comments and test case
(cherry picked from commit ac9a5b6d164b3824fdfcbf638af8724ec6e2751c)
2025-10-03 20:50:02 -07:00
Andrew Trick
6039ca2240 LifetimeDependenceDiagnostics: extend temp alloc to unreachable.
When a non-Escapable value depends on the address of a trivial value, we use a
special computeAddressableRange analysis to compute the trivial value's
scope. Extend that analysis to include unreachable paths.

Fixes this pattern:

    inlineStorage.span.withUnsafeBytes

where inlineStorage is a trivial type defined in the user module. This
does not reproduce directly with InlineArray, but it is a problem for
user modules that have their own trivial wrapper around an InlineArray.

Fixes rdar://161630684 (Incorrect diagnostic: lifetime-dependent value escapes its scope)

(cherry picked from commit 98b7d5906cffa0cf7a481ba47a6acd746e388ac9)
2025-10-03 20:50:02 -07:00
Andrew Trick
d2dea322e2 Fix computeAddressableRange, test, and comment.
Address review feedback from the previous commit.

(cherry picked from commit 712d39a624)
2025-09-10 21:32:56 -07:00
Andrew Trick
4f0dfc13ea LifetimeDependenceScopeFixup: extend temporary stack allocations
When the source of a lifetime dependency is a stack-allocated address, extend
the stack allocation to cover all dependent uses.

This avoids miscompilations for "addressable" dependencies which arise in code
built with -enable-experimental-feature AddressableTypes or
AddressableParameters. It is always an error for SILGen to emit the alloc_stack
in such cases. Nonetheless, we want to handle these unexpected cases gracefully
in SIL as a diagnostic error rather than allowing a miscompile.

Fixes rdar://159680262 ([nonescapable] diagnose dependence on a
temporary copy of a global array)

(cherry picked from commit 7dfd1057111425d3902b1b17cd2129c94f974027)
2025-09-10 21:32:56 -07:00
Andrew Trick
45a98a7209 LifetimeDependenceDiagnostics: check for on-stack trivial copies
Add a diagnostic to catch addressable dependencies on a trivial values that have
been copied to a temporary stack location. SILGen should never copy the source
of an addressable dependency to a temporary stack location, but this diagnostic
catches such compiler bugs rather than allowing miscompilation.

Fixes rdar://159680262 ([nonescapable] diagnose dependence on a temporary copy
of a global array)
2025-09-10 21:32:55 -07:00
Andrew Trick
d03fd679b8 Merge pull request #82797 from atrick/62-local-deadend
[6.2] Improve LocalVariableUtils.gatherKnownLifetimeUses; dead ends
2025-07-07 08:17:15 -07:00
eeckstein
092441e60a Merge pull request #82799 from eeckstein/fix-escape-utils-6.2
[6.2] EscapeUtils: consider that a pointer argument can escape a function call
2025-07-07 16:04:57 +02:00
Erik Eckstein
33c91065b7 Optimizer: add var insertedPhis in SSAUpdater 2025-07-04 20:37:45 +02:00
Erik Eckstein
fc7c9931b3 EscapeUtils: consider that a pointer argument can escape a function call
Unlike addresses of indirect arguments, a pointer argument (e.g. `UnsafePointer`) can escape a function call.
For example, it can be returned.

Fixes a miscompile
rdar://154124497
2025-07-04 11:56:03 +02:00
Andrew Trick
9f7bf2a507 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)

(cherry picked from commit 239255b8bc)
2025-07-03 21:34:25 -07:00
Andrew Trick
43193b6a4d 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)

(cherry picked from commit fe9c0dd735)
2025-06-28 09:30:55 -07:00
Andrew Trick
04cb1a3c1e Fix lifetime diagnotics on an empty tuple.
Consider an empty tuple to be a value introducer rather than a forwarding
instruction.

Fixes rdar://153978086 ([nonescapable] compiler crash with dependency on an
expression)

(cherry picked from commit bcc4a78c42)
2025-06-24 00:11:46 -07:00
Andrew Trick
0116dc0ff9 LifetimeDependenceScopeFixup: handle yielded value copies.
When extending an access scope over a coroutines, instead of simply
considering the lifetime of the coroutine scope, recurse through all
uses of yielded values. They may be copyable, non-Escapable values
that depend on the coroutine operand.

Fixes rdar://152693622 (Extend coroutines over copied yields)

(cherry picked from commit 227f8028e8)
2025-06-05 20:24:18 -07:00
Andrew Trick
b862300097 LifetimeDependenceDiagnostics: diagnose indirect closure results.
Add support for diagnosing calls to closures that return a generic
non-Escapable result.

Closures do not yet model lifetime dependencies. The diagnostics have
a special case for handling nonescaple result with no lifetime
dependence, but it previously only handled direct results. This fix handles
cases like the following:

    func callIndirectClosure<T>(f: () -> NE<T>) -> NE<T> {
      f()
    }

Fixes rdar://134318846 ([nonescapable] diagnose function types with nonescapable results)

(cherry picked from commit 1d09c06ab1)
2025-06-04 12:03:35 -07:00
Andrew Trick
6f05d80161 LifetimeDependenceDefUseAddressWalker: avoid infinite recursion.
This utility is used by DependentAddressUseDefWalker which now conservatively
follows all possible uses. This could result in the same address being reached
multiple times during a def-use walk. Ensure that we don't infinitely recurse.

There is no small test case for this, but the fix is trivial and standard
practice for such walkers, and this is hit quickly in real usage, so there is no
danger of it regressing.

Fixes rdar://150403948 ([nonescapable] Infinite recursion compiler crash in
lifetime dependence checking)

(cherry picked from commit 4512927d2b)
2025-05-01 17:10:59 -07:00
Meghana Gupta
cc72edb119 Introduce end_cow_mutation_addr instruction 2025-04-30 14:38:48 -07:00
Andrew Trick
4c78ece643 LifetimeDependence: clarify diagnostics for many unusual cases.
Ensure that we always issue a diagnostic on error, but avoid emitting any notes that don't have source locations.

With implicit accessors and thunks, report the correct line number and indicate which accessor generates the error.

Always check for debug_value users.

Consistently handle access scopes across diagnostic analysis and diagnostic messages.

(cherry picked from commit ec512864eb)
2025-04-30 00:09:40 -07:00
Andrew Trick
63619e8a34 LifetimeDependenceDiagnostics: avoid infinite recursion on error
Fix a simple typo that results in infinite recursion on invalid code.

Fixes rdar://147470493 ([nonescapable] LifetimeDependenceInsertion: infinite
recursion in VariableUseDefWalker.walkup with immortal setter)

(cherry picked from commit c891d8ade4)
2025-04-30 00:09:39 -07:00
Erik Eckstein
78bfc9f955 RedundantLoadElimination: support replacing a redundant copy_addr with a store
For example:
```
  %0 = load %1
  copy_addr %1 to %2
```
->
```
  %0 = load %1
  store %0 to %2
```

This is important for MandatoryRedundantLoadElimination to be able to create statically initialized globals in the mandatory pipeline.
For example:
```
public struct MyStruct {
  public static let r: Range<Int> = 1 ..< 3
}

```
gets a statically initialized global, even at Onone, with this improvement.

rdar://149356742
2025-04-28 08:01:49 +02:00
Andrew Trick
4fbf0db621 [NFC] LifetimeDependenceUtils comment
(cherry picked from commit 060364546a)
2025-04-25 19:21:15 -07:00
Andrew Trick
3674d08c2b Fix LifetimeDependenceDiagnostics: handle address-only 'let's
Add a case to LifetimeDependence.Scope to support dependencies on address-only
'let' variables. This comes up with C++ interop.

Fixes rdar://147500193 (Spurious lifetime error with closures)

(cherry picked from commit 5831777407)
2025-04-23 23:01:31 -07:00
Andrew Trick
bb6b5b3645 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)
(cherry picked from commit 3b08592ed2)
2025-04-22 22:46:41 -07:00
Andrew Trick
161158806e LifetimeDependenceScopeFixup: handle returning dependent Optional
Add support for returnValue phis (e.g. to return an Optional .some or .none).

Fixes rdar://149397018 (Wrapping non escapable in an Optional
(or any copy lifetime wrapper) is an escape)

(cherry picked from commit a1aaed9159)
2025-04-21 22:57:06 -07:00
Andrew Trick
ff7cc60923 Fix unidentified LifetimeDependence.Scope initialization.
Fixes rdar://149226564 (Compiler crash with non-escapable storing another
non-escapable and having a deinit)

(cherry picked from commit 6f8605263d)
2025-04-16 23:32:00 -07:00
Andrew Trick
2fbc9032f5 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.

(cherry picked from commit 4e35d255ad)
2025-04-16 23:31:53 -07:00
Andrew Trick
5269c0c8e7 [NFC] Add LifetimeDependenceUseDefWalker utility.
Refactor VariableIntroducerUseDefWalker into a general
LifetimeDependenceUseDefWalker for use with LifetimeDependenceScopeFixup.

(cherry picked from commit b80bd16eea)
2025-04-16 23:23:55 -07:00
Andrew Trick
cc949bdaa7 [NFC] minor cleanup
(cherry picked from commit 43debc529f)
2025-04-16 23:23:55 -07:00
Andrew Trick
32fc6ad623 Add InstructionRange.overlapsWithPath() utility.
(cherry picked from commit 28daec01a7)
2025-04-16 23:23:54 -07:00
Andrew Trick
e60e65538a SwiftCompilerSources: add IgnoredUseInst as incidental
Fixes rdar://148540048 (Assigning span value to `_` results in an incorrect escape diagnostic)

(cherry picked from commit 2bdaa68e98)
2025-04-16 23:23:54 -07:00
Andrew Trick
fa39b4172b 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)

(cherry picked from commit c9279d9899)
2025-04-16 23:23:54 -07:00
Andrew Trick
e01a167db1 LocalVariableUtils: add unit tests
(cherry picked from commit ccb26bcd89)
2025-04-11 00:29:02 -07:00
Andrew Trick
c9c0ef843c 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.

(cherry picked from commit 37ecd0e9bd)
2025-04-11 00:28:52 -07:00
Andrew Trick
bf6ed014dd Fix escape analysis: addressable parameters.
An address-type parameter may escape via an indirect argument if the function's
result depends on the argument's address.

(cherry picked from commit 05a9acbb40)
2025-04-08 14:09:54 -07:00
Erik Eckstein
ee18f8c168 Simplification: fix a crash in alloc_stack simplification
Handle the case that a type dependent operand is a dynamic-self argument and not an open-existential instruction.

rdar://148258964
2025-04-01 10:58:45 +02:00
Andrew Trick
97b249bd11 Merge pull request #80263 from atrick/markdep-addr
SIL: add mark_dependence_addr
2025-03-26 10:33:42 -07:00
Erik Eckstein
380ea889bc SIL: fix self-argument APIs in Function
`var selfArgument` should return an optional, i.e. nil if the function doesn't have a self argument.
2025-03-26 07:30:10 +01: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
ea8cb3c1b4 LifetimeDependenceDiagnostics: recognize store_borrow ranges
Avoid an unnecessary diagnostic when the dependent value's uses are covered by a
StoreBorrow.
2025-03-20 12:17:24 -07:00
Slava Pestov
8bcd09aaa4 SIL: Preliminary refactoring of SILWitnessTable::AssociatedConformanceWitness
The Protocol field isn't really necessary, because the conformance
stores the protocol. But we do need the substituted subject type
of the requirement, just temporarily, until an abstract conformance
stores its own subject type too.
2025-03-18 19:38:42 -04:00
Andrew Trick
ce18a4bce8 Merge pull request #79985 from atrick/fix-destroyhoist
Fix DestroyHoisting: InteriorLiveness for noescape closures
2025-03-18 05:07:27 -07:00
Erik Eckstein
37455b6ab6 Optimizer: use formal types instead of SIL types for classifying dynamic casts.
Casts always work with formal rather than lowered types.
This fixes a potential bug when lowered types are different than formal types, like function types.
2025-03-14 09:45:27 +01:00
Erik Eckstein
d52f7d1619 AST/SIL: Refactor and simplify AST.Type, AST.CanonicalType and SIL.Type
* let `SIL.Type` conform to `TypeProperties` to share the implementation of common type properties between the AST types and `SIL.Type`
* call references to an `AST.Type` `rawType` (instead of just `type`)
* remove unneeded stuff
* add comments
2025-03-14 09:40:22 +01:00
Andrew Trick
995c74966d Fix DestroyHoisting: InteriorLiveness for noescape closures
InteriorLiveness has a new "visitInnerUses" mode used by DestroyHoisting. That
mode may visit dependent values, which was not valid for noescape
closures. ClosureLifetimeFixup inserts destroys of noescape closures after the
destroys of the captures. So following such dependent value could result in an
apparent use-after-destroy. This causes DestroyHoisting to insert redundant
destroys.

Fix: InteriorUses will conservatively only follow dependent values if they are
escapable. Non-escapable values, like noescape closures are now considered
escapes of the original value that the non-escapable value depends on. This can
be improved in the future, but we may want to rewrite ClosureLifetimeFixup first.

Fixes the root cause of: rdar://146142041
2025-03-13 09:17:31 -07:00
Erik Eckstein
23b4c6fc34 embedded: fix specialization of associated conformance entries in witness tables
When creating a specialized witness table, we need to get the right specialized conformance.
In IRGen don't emit associated conformance witness table entries if the protocol is not a class protocol.
In this case the associated type can never be used to create an existential. Therefore such a witness table entry is never used at runtime in embedded swift.

Fixes a compiler crash

rdar://146448091
2025-03-11 11:33:10 +01:00
Erik Eckstein
5016e35880 Optimizer: add two small utilities for instructions
* `func Instruction.dominatesInSameBlock(_ otherInst: Instruction) -> Bool`
* `var Instruction.concreteTypeOfDependentExistentialArchetype`
2025-03-07 15:59:34 +01:00
Erik Eckstein
810064b7dc Cleanup and additions to AST and SIL Type/CanonicalType
* factor out common methods of AST Type/CanonicalType into a `TypeProperties` protocol.
* add more APIs to AST Type/CanoncialType.
* move `MetatypeRepresentation` from SIL.Type to AST.Type and implement it with a swift enum.
* let `Builder.createMetatype` get a CanonicalType as instance type, because the instance type must not be a lowered type.
2025-03-07 15:59:33 +01:00
Andrew Trick
b3f401d346 LifetimeDependenceScopeFixup: handle indirect yields & fix bugs
Handle coroutines that yield an address. Fix bugs involving extension of
multiple nested scopes that depend on multiple coroutine operands.
2025-03-05 02:12:21 -08:00
Andrew Trick
3019c843be LifetimeDependence: allow dependence on the store_borrow address
Previously, the dependence was on the stored value, but that is incorrect for
'@'_addressable parameters.
2025-03-03 11:56:37 -08:00
Andrew Trick
bc6200e592 SwiftCompilerSources: bridge '@'_addressable dependencies 2025-03-03 11:56:37 -08:00