rdar://167713693
The LoadableByAddress pass recognizes large loadable types in borrow accessors and returns them by @guaranteed_address.
This prevents stack allocations and unnecessary copies.
Co-authored-by: Meghana Gupta <meghana_gupta@apple.com>
When compiling for a triple that predates typed throws,
`swift_getFunctionMetadataExtended` is conditionally available and emitted as a
weak external symbol. Previously, when such code ran on a older runtime where
`swift_getFunctionMetadataExtended` was uanvailable, accessing function metadata
for a `nonisolated(nonsending)` function would crash by invoking the null
`swift_getFunctionMetadataExtended`.
This patch adds a runtime null check when emitting metadata accessors for simple
`nonisolated(nonsending)` functions (those without typed throws or other
extended flags) in such situations. If `swift_getFunctionMetadataExtended` is
unavailable at runtime, we fall back to `swift_getFunctionMetadata`, returning
`@concurrent` function metadata instead.
This trade-off is acceptable because:
- Function metadata is not required to call a `nonisolated(nonsending)` function
- This enables use of these functions in frameworks like SwiftUI on older OS versions
Known limitations of the fallback path:
- Dynamic casts between `nonisolated(nonsending)` and `@concurrent` will incorrectly succeed
- Reflection will report `nonisolated(nonsending)` functions as `@concurrent`
- Existential erasure will lose the `nonisolated(nonsending)` attribute
These edge cases will produce obvious crashes during testing if misused, since
`nonisolated(nonsending)` expects its first parameter to be an actor while
`@concurrent` does not. This makes the increased compatibility worth the
trade-off.
rdar://158970802
This new OSSA invariant simplifies many optimizations because they don't have to take care of the corner case of incomplete lifetimes in dead-end blocks.
The implementation basically consists of these changes:
* add the lifetime completion utility
* add a flag in SILFunction which tells optimization that they need to run the lifetime completion utility
* let all optimizations complete lifetimes if necessary
* enable the ownership verifier to check complete lifetimes
These two new invariants eliminate corner cases which caused bugs if optimization didn't handle them.
Also, it will significantly simplify lifetime completion.
The implementation basically consists of these changes:
* add a flag in SILFunction which tells optimization if they need to take care of infinite loops
* add a utility to break infinite loops
* let all optimizations remove unreachable blocks and break infinite loops if necessary
* add verification to check the new SIL invariants
The new `breakIfniniteLoops` utility breaks infinite loops in the control flow by inserting an "artificial" loop exit to a new dead-end block with an `unreachable`.
It inserts a `cond_br` with a `builtin "infinite_loop_true_condition"`:
```
bb0:
br bb1
bb1:
br bb1 // back-end branch
```
->
```
bb0:
br bb1
bb1:
%1 = builtin "infinite_loop_true_condition"() // always true, but the compiler doesn't know
cond_br %1, bb2, bb3
bb2: // new back-end block
br bb1
bb3: // new dead-end block
unreachable
```
We turn off the AllowMarkerProtocols mangler flag when
mangling the types that are passed into the runtime demangler.
The logic in appendAnyProtocolConformance() was wrong when
this flag was set; we would early exit from this function,
but then appendRetroactiveConformances() would still call
appendListSeparator(). The would result in an invalid mangled
string which could not be parsed by the demangler.
In particular, this meant that the recent changes to generalize
Equatable to allow non-Copyable and non-Escapable conformers
could introduce runtime crashes, because a mangled string for
a retroactive conformance to Equatable could be incorrect.
The fix is to handle AllowMarkerProtocols further up in
forEachConditionalConformance().
Note that this change should not directly change ABI, because
AllowMarkerProtocols is on for symbol names.
When AllowMarkerProtocols is on, we still always mangle
conformances to Copyable and Escapable in this code path.
This means that even with this change, mangling a symbol name
that contains a retroactive conformance to Equatable can output
a different string than in Swift 6.3, which means we have an ABI
break. That problem requires a separate fix.
- Fixes rdar://problem/168023786.
This makes these symbols visible in backtraces, at the cost of binary size.
The long-term goal is to generate these functions with LinkOnceODRLinkage, using
the contents of the HeapLayout to produce a mangled name, so they can be
deduplicated across modules.
In order to make the symbols more meaningful when they appear in backtraces,
use the name parameter passed to emitUnmanagedAlloc to produce a destructor name
with the format __swift_{name}_destructor.
rdar://149084103
This does not rename all the internal variables, functions, and types
whose names were based on the old syntax.
I think it adds new syntax support everywhere it's needed while
retaining enough of the old syntax support that early adopters will
see nice deprecation messages guiding them to the new syntax.
rdar://163631865
Under certain circumstances the same symbol can be used for different implementations of the forwarders.
The forwarders themselves are already emitted with "internal" LLVM linkage, but some particularities in
the mapping from SILLinkage to LLVM linkage caused async function pointers to partial apply forwarders
to be emitted with linkonce_odr instead, which caused the wrong forwarder to be called at runtime, causing
unexpected behavior and crashes.
This sanitizer adds MTE (memory tagging extension) checks to stack
variable accesses. Enablement simply requires setting an attribute on
function definitions, and the instrumentation is added by LLVM.
The corresponding swift-driver change is at:
https://github.com/swiftlang/swift-driver/pull/2016.
rdar://161721201
`irgen::addGenericRequirements` will later filter out Copyable
and Escapable requirements, so this field's count isn't accurate
if it's using the pre-filtered number.
This should in theory only affect the metadata emission for keypaths,
specifically, the caller `IRGenModule::getAddrOfKeyPathPattern`.
Before this change, we were sometimes using introductory platform version as the starting version where
a symbol is considered belonging to the original binary. However, this is insufficient
because backdeploying to a platform version prior to a symbol's introductory version can happen. When it
happens, we should expect the moved symbol to be found in the moved-from library, not the moved-to one. Expecting
the symbol to be found in the moved-to library can lead to crasher.
Resolves: rdar://159408187
When performing multi-threaded IRGen, all of the link libraries used
for autolinking went (only) into the first object file. If the object
files were then placed in a static archive, the autolinking would only
kick in if clients that link the static library reference something in
the first object file. This causes link failures.
Make sure that we put the autolink information into each of the object
files we create when doing multi-threaded IRGen.
Fixes the rest of rdar://162400654.
With multi-threaded IRGen, the global variables associated with "once"
initialization tokens were not getting colocated with their actual
global variables, which caused the initialization code to get split
across different files. This issue manifest as autolinking errors in
some projects.
Fixes rdar://162400654.