Commit Graph

9 Commits

Author SHA1 Message Date
Allan Shortlidge
022abe4d3b NFC: Update tests to use accepted spelling for @backDeployed. 2023-02-01 22:04:33 -08:00
Allan Shortlidge
5b942eb18b SILGen/Sema: Add @_backDeploy support for constructors.
Resolves rdar://94436652
2023-01-21 18:04:54 -08:00
Allan Shortlidge
9f54e9cd1f SILGen: Fix double-free of __owned parameters of functions with @_backDeploy.
The following program crashed when compiled with the Swift 5.7 and 5.8 compilers:

```
@available(macOS 12, *)
@_backDeploy(before: macOS 99)
public func foo<T>(_ t: __owned T) {
  print("foo")
}

class C {
  deinit {
    print("deinit")
  }
}

foo(C())
print("done")
```

```
> ./test
foo
deinit
[1]    49162 segmentation fault  ./test
```

The root cause is that generated SIL for the back deployment thunk for `foo(_:)` included its own `destroy_addr` instruction for the value of `t`, but didn't copy the parameter before passing it to the real function implementation which also destroys the value. The fix is to forward ownership of the parameter values to the called function, which causes cleanup generation to be skipped.

Resolves rdar://104436515
2023-01-19 13:12:02 -08:00
Allan Shortlidge
95a9310e11 SILGen: Fix 'multiple definitions of symbol' error for functions with @_backDeploy containing defer blocks.
If the emission of a function is delayed via `emitOrDelayFunction()`, then the function is recorded on a list of delayed functions. If the delayed function is later referenced, then the function moves from the delayed list to the "forced" list which will cause it to actually be emitted later. The implementation of `emitOrDelayFunction()` had a bug when called twice for the same delayable function - it would emit that function prematurely if the function moved to the forced list between the two invocations. Later, during forced function emission a multiple definitions of symbol diagnostic would be emitted since the function was not empty.

This issue could be triggered by `@_backDeploy` functions that have auxilary delayable helper functions (e.g. defer blocks). SILGen visits `@_backDeploy` functions twice (once for the copy of the function emitted into the client and once for the resilient copy of the function) so `emitOrDelayFunction()` is called twice for each of the helper functions and the helper functions could become referenced between the two calls.

The fix is to check for an existing entry in the forced functions list before delaying or emitting a delayable function.

Resolves rdar://102909684
2022-12-07 20:51:39 -08:00
Allan Shortlidge
080d850153 Sema: Allow @inlinable on back deployed functions.
Per Swift Evolution feedback, back deployed functions should be allowed to be inlinable, even though this means that the version of the function in the library may not always be exectued when it is otherwise available.

Resolves rdar://102792806
2022-11-29 18:42:44 -08:00
Allan Shortlidge
405b7b7b9e NFC: Update @_backDeploy runtime tests to call a coroutine that yields a non-trivial value.
This is a follow up to #60021 to ensure that a test exists that would cause lifetime verification to fail if the fix regressed.
2022-07-13 10:17:51 -07:00
Allan Shortlidge
019a345932 SILGen: Generate appropriate SIL for @_backDeploy thunks that wrap coroutine functions (such as the _read and _modify accessors). Remove the temporary diagnostics that rejected use of @_backDeploy on decls that would result in coroutines. 2022-03-24 15:42:14 -07:00
Allan Shortlidge
59b62c2cc9 NFC: Update tests to include "before: " label in the @_backDeploy attribute. 2022-03-18 11:24:47 -07:00
Allan Shortlidge
c09df4910d Tests: Add integration tests for @_backDeploy that verify that use of declarations annotated with @_backDeploy behave as expected when running a client binary on an older OS that does not have the back deployed APIs.
APIs with a variety of function signatures (inout parameters, throwing, generic, existential parameters and return values, etc.) are exercised to verify SILGen for these cases.
2022-03-16 00:33:24 -07:00