Commit Graph

47 Commits

Author SHA1 Message Date
Meghana Gupta
21cc1a185b Add memory lifetime verification support for borrow accessors 2025-11-06 10:55:42 -08:00
Nate Chandler
a241cf5e59 [MemoryLifetimeVerifier] Permit leaks in dead-ends 2025-08-27 18:05:07 -07:00
Hamish Knight
edca7c85ad Adopt ABORT throughout the compiler
Convert a bunch of places where we're dumping to stderr and calling
`abort` over to using `ABORT` such that the message gets printed to
the pretty stack trace. This ensures it gets picked up by
CrashReporter.
2025-05-19 20:55:01 +01:00
Andrew Trick
d9dd93560d Support mark_dependence_addr in SIL passes. 2025-03-25 23:02:45 -07:00
Erik Eckstein
8d78f75ea4 MemoryLifetimeVerifier: verify inject_enum_addr
Verify that the enum case payload is alive at the point of an inject_enum_addr
rdar://146315214
2025-03-07 19:58:53 +01:00
Erik Eckstein
6a6d3f0b13 SIL: handle mark_dependence in the MemoryLifetimeVerifier
The check is not perfect, because it only checks that the base operand is alive _at_ the mark_dependence.
Ideally it should check that the base operand is alive during the whole lifetime of the value operand.
2025-02-10 17:57:47 +01:00
Akira Hatanaka
42bc49d3fe Add a new parameter convention @in_cxx for non-trivial C++ classes that are passed indirectly and destructed by the caller (#73019)
This corresponds to the parameter-passing convention of the Itanium C++
ABI, in which the argument is passed indirectly and possibly modified,
but not destroyed, by the callee.

@in_cxx is handled the same way as @in in callers and @in_guaranteed in
callees. OwnershipModelEliminator emits the call to destroy_addr that is
needed to destroy the argument in the caller.

rdar://122707697
2024-06-27 09:44:04 -07:00
Joe Groff
636a19d11b Merge pull request #74707 from jckarter/consume-during-borrow-checks
MoveOnlyAddressChecker: More robust checking for consume-during-borrow.
2024-06-26 08:22:04 -07:00
Joe Groff
27a8852290 MoveOnlyAddressChecker: More robust checking for consume-during-borrow.
- While an opaque borrow access occurs to part of a value, the entire scope of
  the access needs to be treated as a liveness range, so add the `EndAccess`es
  to the liveness range.
- The SIL verifier may crash the compiler on SILGen-generated code when the
  developer's source contains consume-during-borrow code patterns. Allow
  `load_borrow` instructions to be marked `[unchecked]`, which suppresses
  verifier checks until the move checker runs and gets a chance to properly
  diagnose these errors.

Fixes rdar://124360175.
2024-06-25 14:10:02 -07:00
Tim Kientzle
1098054291 Merge branch 'main' into tbkka-assertions2 2024-06-18 17:52:00 -07:00
Akira Hatanaka
d92f181ace Create two versions (for caller and callee) of the functions that answer questions about parameter convention (#74124)
Create two versions of the following functions:

isConsumedParameter
isGuaranteedParameter
SILParameterInfo::isConsumed
SILParameterInfo::isGuaranteed
SILArgumentConvention::isOwnedConvention
SILArgumentConvention::isGuaranteedConvention

These changes will be needed when we add a new convention for
non-trivial C++ types as the functions will return different answers
depending on whether they are called for the caller or the callee. This
commit doesn't change any functionality.
2024-06-18 09:06:09 -07:00
Tim Kientzle
1d961ba22d Add #include "swift/Basic/Assertions.h" to a lot of source files
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
2024-06-05 19:37:30 -07:00
Emil Pedersen
00a93d939c Fix inverted condition in MemoryLifetimeVerifier 2024-04-24 18:23:39 -07:00
Meghana Gupta
b6ed0d41a7 Handle switch_value in MemoryLifetimeVerifier 2024-04-03 10:30:55 -07:00
Joe Groff
2722f1adcd MemoryLifetimeVerifier: Treat only destructive enum_data_addr insns as writes.
It is ok to project the data from an enum in cases where we know spare bit
packing can never happen. Fixes rdar://124240723.
2024-03-11 09:49:57 -07:00
Andrew Trick
23ddaafdc8 Fix MemoryLifetimeVerifier to ignore thin functions.
SILGen optimizes creation of closure down a thin function when it has
no captures:

  %1 = thin_to_thick_function %0
  : $@convention(thin) () -> () to $@callee_guaranteed () -> ()

ValueOwnership.cpp has a sketchy optimization that treat the result
like a trivial type, even though it is not:

>  CONSTANT_OWNERSHIP_INST(None, ThinToThickFunction)

commit 8c5737d1d5
Date:   Fri Oct 23 15:12:18 2020 -0700

    [ownership] Change thin_to_thick function to always produce a none value.

This creates a mismatch between the SILType and the SILValue
ownership. This is not a coherent design--we have a similar problem
with enums which is endlessly buggy--but reverting the decision will
be hard. Instead, I'll hack the memory verifier to silence this case.

Fixes rdar://115735132 (Lifetime verifier error with opaque return
type and closure)
2023-12-05 09:16:07 -08:00
Erik Eckstein
0897d8a720 MemoryLifetimeVerifier: use CalleeCache instead of AliasAnalysis
To verify if a function may read from an indirect argument, don't use AliasAnalysis.
Instead use the CalleeCache to get the list of callees of an apply instruction.
Then use a simple call-back into the swift Function to check if a callee has any relevant memory effect set.

This avoids a dependency from SIL to the Optimizer.
It fixes a linker error when building some unit tests in debug.
2023-12-01 19:20:18 +01:00
Michael Gottesman
b1f69030fc [region-isolation] When assigning RValues into memory, use tuple_addr_constructor instead of doing it in pieces.
I also included changes to the rest of the SIL optimizer pipeline to ensure that
the part of the optimizer pipeline before we lower tuple_addr_constructor (which
is right after we run TransferNonSendable) work as before.

The reason why I am doing this is that this ensures that diagnostic passes can
tell the difference in between:

```
x = (a, b, c)
```

and

```
x.0 = a
x.1 = b
x.2 = c
```

This is important for things like TransferNonSendable where assigning over the
entire tuple element is treated differently from if one were to initialize it in
pieces using projections.

rdar://117880194
2023-11-07 15:38:33 -08:00
Michael Gottesman
6a65c7829e [sil] Add tuple_addr_constructor an instruction that can be used to initial a tuple in memory from individual address and object components.
This commit just introduces the instruction. In a subsequent commit, I am going
to add support to SILGen to emit this. This ensures that when we assign into a
tuple var we initialize it with one instruction instead of doing it in pieces.
The problem with doing it in pieces is that when one is emitting diagnostics it
looks semantically like SILGen actually is emitting code for initializing in
pieces which could be an error.
2023-11-06 15:32:05 -08:00
Slava Pestov
863604e393 SIL: Fix MemoryLifetimeVerifier for try_apply with indirect error result 2023-10-31 16:58:54 -04:00
Slava Pestov
eac491ccd2 SIL: Fix memory lifetime verifier check for the thrown error result 2023-10-27 17:37:43 -04:00
Erik Eckstein
bad87c4c1e MemoryLifetimeVerifier: relax the check for trivial enums a bit
Trivial enum cases in a memory location don't need to be destroyed.
Don't require that the store to such a memory location is statically known as a trivial enum case.
Instead just require that it's below a switch_enum successor for a trivial case.

Fixes a false alarm.

rdar://114274714
2023-08-23 12:48:46 +02: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
Erik Eckstein
4b33b99ee2 MemoryLifetimeVerifier: be more precise with indirect function arguments.
Optimizations can rely on alias analysis to know that an in-argument (or parts of it) is not actually read.
We have to do the same in the verifier: if alias analysis says that an in-argument is not read, there is no need that the memory location is initialized.

Fixes a false verifier error.
rdar://106806899
2023-05-03 14:33:45 +02:00
John McCall
d25a8aec8b Add explicit lowering for value packs and pack expansions.
- SILPackType carries whether the elements are stored directly
  in the pack, which we're not currently using in the lowering,
  but it's probably something we'll want in the final ABI.
  Having this also makes it clear that we're doing the right
  thing with substitution and element lowering.  I also toyed
  with making this a scalar type, which made it necessary in
  various places, although eventually I pulled back to the
  design where we always use packs as addresses.

- Pack boundaries are a core ABI concept, so the lowering has
  to wrap parameter pack expansions up as packs.  There are huge
  unimplemented holes here where the abstraction pattern will
  need to tell us how many elements to gather into the pack,
  but a naive approach is good enough to get things off the
  ground.

- Pack conventions are related to the existing parameter and
  result conventions, but they're different on enough grounds
  that they deserve to be separated.
2023-01-29 03:29:06 -05:00
Meghana Gupta
4d77b82c12 Update store_borrow verification in MemoryLifetimeVerifier
- Ensure there are no double end_borrows
- Ensure there are no end_borrows after dealloc_stack of the dest
2022-12-14 02:08:34 -08:00
nate-chandler
7768b005a7 Merge pull request #62501 from nate-chandler/remove-in-constant
[SIL] Removed Indirect_In_Constant convention.
2022-12-12 07:29:12 -08:00
Nate Chandler
8d8577e5b0 [SIL] Removed Indirect_In_Constant convention.
It is no different from @in.

Continue parse @in_constant in textual and serialized SIL, but just as
an alias for @in.
2022-12-09 21:54:00 -08:00
Nate Chandler
570a58385d [NFC] Tweaked memory verifier require messages.
Grammar.
2022-12-09 11:16:30 -08:00
Nate Chandler
7430c6142f [SIL] Verified yielded addresses.
For yielded, nontrivial addresses, verify based on convention:
- guaranteed -> must be initialized at end_apply/abort_apply
- owned -> must be deinitialized at end_apply/abort_apply
- inout -> must be initialized at end_apply/abort_apply
2022-12-07 18:51:50 -08:00
Meghana Gupta
5244e6f3d5 Improve verification for store_borrow
Add ScopedAddressOperand and ScopedAddressValue abstraction utilities
Introduce verification for store_borrow to validate its uses are correctly enclosed in their scope.

Include end_borrow/end_access as implicit uses while validating a borrow introducer

Add flow sensitive verifier rule for store_borrow/end_borrow pair

Make sure store_borrow is always to an alloc_stack

Make sure uses to store borrow location are via its return address only
2022-08-16 15:08:22 -07:00
Erik Eckstein
32a4a6772e MemoryLifetimeVerifier: fix verification of store_borrow locations
In case of a single-block location, the verification of store_borrow locations didn't work in all cases.
2022-06-10 11:12:35 +02:00
Josh Soref
d767912be2 Spelling sil (#42471)
* spelling: accessible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: accessories

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: allocated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: amortizes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: are

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: arguments

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: cacheable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: check

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compatible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: compilation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: completely

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: construct

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declarations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: derivation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: deserialization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: destroyed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: determined

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: different

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: doesn't

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equality

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equivalent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: formation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: forwards

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: global

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: guaranteed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: have

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: identify

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inaccessible

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indeterminate

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indices

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inefficient

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: inheritance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instantaneous

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instruction

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intentionally

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interior

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: intrinsic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: introducing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: irrelevant

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: message

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: multi

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessarily

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: object

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: one

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: optimization

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: otherwise

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameter

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: pattern

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: pipeline

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: possibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: postdominance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: providing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: reached

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recognized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: refrigerator

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: remaining

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: resilient

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: retrieve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scavenge

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scheduled

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: separately

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: serializable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: signature

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplicity

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specifically

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substituted

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substitution

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: subtypes

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: supplement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: syntax

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: there

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: these

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: this

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: though

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: through

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transitively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transpose

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: trivial

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: value

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: verification

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: visibility

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: weird

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: whole

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-22 15:11:09 -07:00
Erik Eckstein
90695d9cdf TempRValueElimination: fix a problem with leaking enum values
When optimizing an enum `store` to an `alloc_stack`, require that all uses are in the same block.
Otherwise it could be a `switch_enum` of an optional where the none-case does not have a destroy of the enum value.
After transforming such an `alloc_stack`, the value would leak in the none-case block.

Fixes a OSSA verification error.
2022-03-08 15:47:14 +01:00
Nate Chandler
02207288a3 [Gardening] Tweaked verifier wording.
Added trailing "be" to match "is" in "memory is [not] initialized, but
should[n't]".  The errors are now "meemory is [not] initialized, but
should[n't] be".
2022-02-23 08:21:56 -08:00
Michael Gottesman
d74299e68d [move-function] Add a new instruction called mark_unresolved_move_addr.
This instruction is similar to a copy_addr except that it marks a move of an
address that has to be checked. In order to keep the memory lifetime verifier
happy, the semantics before the checker runs are the mark_unresolved_move_addr is
equivalent to copy_addr [init] (not copy_addr [take][init]).

The use of this instruction is that Mandatory Inlining converts builtin "move"
to a mark_unresolved_move_addr when inlining the function "_move" (the only
place said builtin is invoked).

This is then run through a special checker (that is later in this PR) that
either proves that the mark_unresolved_move_addr can actually be a move in which
case it converts it to copy_addr [take][init] or if it can not be a move, emit
an error and convert the instruction to a copy_addr [init]. After this is done
for all instructions, we loop back through again and emit an error on any
mark_unresolved_move_addr that were not processed earlier allowing for us to
know that we have completeness.

NOTE: The move kills checker for addresses is going to run after Mandatory
Inlining, but before predictable memory opts and friends.
2021-12-06 12:47:29 -08:00
Erik Eckstein
1bf0a08de3 Make the MemoryLifetimeVerifier more picky about double destroys of trivial enums
Not destroying an enum with a trivial case is okay, but a double destroy is not.

rdar://85049084
2021-11-10 12:33:38 +01:00
Erik Eckstein
36c6f999dc SIL: Improve comments of MemoryLocations and MemoryVerifier 2021-09-09 11:19:49 +02:00
Erik Eckstein
74151a970b MemoryLifetimeVerifier: treat enum cases with empty payloads (e.g. an empty tuple) like cases with no payloads. 2021-09-09 11:19:49 +02:00
Min-Yih Hsu
343d842394 [SIL][DebugInfo] PATCH 3/3: Deprecate debug_value_addr SIL instruciton
This patch removes all references to DebugValueAddrInst class and
debug_value_addr instruction in textual SIL files.
2021-08-31 12:01:04 -07:00
Min-Yih Hsu
e1023bc323 [DebugInfo] PATCH 2/3: Duplicate logics regarding debug_value_addr
This patch replace all in-memory objects of DebugValueAddrInst with
DebugValueInst + op_deref, and duplicates logics that handles
DebugValueAddrInst with the latter. All related check in the tests
have been updated as well.

Note that this patch neither remove the DebugValueAddrInst class nor
remove `debug_value_addr` syntax in the test inputs.
2021-08-31 11:57:56 -07:00
Erik Eckstein
2755d6552b MemoryLifetimeVerifier: handle stores of tuples with trivial enums
The MemoryLifetimeVerifier issued a false alarm if a tuple with a trivial enum-case (e.g. an Optional nil) is stored to a memory location.

rdar://79781939
2021-06-28 15:09:41 +02:00
Erik Eckstein
b3a7792d1d Reinstate "SIL: add a StackList data structure with zero cost operations."
... with a fix for a non-assert build crash: I used the wrong ilist type for SlabList. This does not explain the crash, though. What I think happened here is that llvm miscompiled and put the llvm_unreachable from the Slab's deleteNode function unconditionally into the SILModule destructor.
Now by using simple_ilist, there is no need for a deleteNode at all.
2021-04-13 13:49:45 +02:00
Arnold Schwaighofer
ddfdf4779d Revert "SIL: add a StackList data structure with zero cost operations." 2021-04-12 12:48:16 -07:00
Erik Eckstein
0456d95cb0 SIL: Use StackList in BasicBlockWorklist and BasicBlockSetVector
plus: I moved both data structures into a separate header file.
2021-04-11 14:07:26 +02:00
Erik Eckstein
b9c8e57d7a MemoryLifetimeVerifier: also verify locations with trivial types.
It helps to catch more problems
2021-03-13 10:41:30 +01:00
Erik Eckstein
1baf009c06 refactoring: Split MemoryLifetime.cpp/h into three separate files
And rename MemoryDataflow -> BitDataflow.

MemoryLifetime contained MemoryLocations, MemoryDataflow and the MemoryLifetimeVerifier.
Three independent things, for which it makes sense to have them in three separated files.

NFC.
2021-03-13 10:41:30 +01:00