This patch adds support for serialization of debug value instructions. Enablement is currently gated behind the -experimental-serialize-debug-info flag.
Previously, debug_value instructions were lost during serialization. This made it harder to debug cross module inlined functions.
If a pass forgot to call invalidateAnalysis but deleted some instructions, the pass-manager can fix this.
Currently following passes do not invalidate analysis when they change the SIL:
* LowerTupleAddrConstructor
* DestroyAddrHoisting
* MoveOnlyChecker
* PredictableDeadAllocationElimination
Ideally we should fix those passes. But with this addition in the pass-manager it's not strictly necessary.
Fixes a compiler crash.
The `maxBitfieldID` was defined as `size_t` and used to assert
bitfield ID values. The `currentBitfieldID` of `SILFunction` is
defined as `uint64_t`, so we should consistently use `uint64_t`
for `maxBitfieldID` as well for 32-bit platforms.
This is necessary to fix a recent OSSA bug that breaks common occurrences on
mark_dependence [nonescaping]. Rather than reverting that change above, we make
forward progress toward implicit borrows scopes, as was the original intention.
In the near future, all InteriorPointer instructions will create an implicit
borrow scope. This means we have the option of not emitting extraneous
begin/end_borrow instructions around intructions like ref_element_addr,
open_existential, and project_box. After that, we can also migrate
GuaranteedForwarding instructions like tuple_extract and struct_extract.
The code here determined the borrow scope of an InteriorPointerOperand use of a borrow using
`visitBaseValueScopeEndingUses`, but it does so after rewriting the operand, so the base
value would sometimes be incorrect leading to missing `end_borrows` in the rewritten code.
Fixes rdar://133333278.
A read access asserts that the memory location is immutable for the duration
of the access, so it can be treated as a borrow rather than a mutable lvalue.
Doing this allows the borrow formal access scope fixes from #79084 to apply
to situations where a loadable type undergoes an accessor-based access with
indirect arguments (such as for public accessors when library evolution is
enabled for the type). Fixes rdar://143334632.
We use the formal source type do decide whether a checked_cast_br is
known to succeed/fail. If we don't update it we loose that optimization
That is:
```
checked_cast_br AnyObject in %2 : X to X, bb1, bb2
```
Will not be simplified even though the operand and the destintation type
matches.
The problem with `is_escaping_closure` was that it didn't consume its operand and therefore reference count checks were unreliable.
For example, copy-propagation could break it.
As this instruction was always used together with an immediately following `destroy_value` of the closure, it makes sense to combine both into a `destroy_not_escaped_closure`.
It
1. checks the reference count and returns true if it is 1
2. consumes and destroys the operand
Improves OSSALifetimeCompletion to handle trivial variables when running from
SILGenCleanup. This only affects lifetime dependence diagnostics.
For the purpose of lifetime diagnostics, trivial local variables are only valid
within their lexical scope. Sadly, SILGen only know how to insert cleanup code
on normal function exits. SILGenCleanup relies on lifetime completion to fix
lifetimes on dead end paths.
%var = move_value [var_decl]
try_apply %f() : $..., normal bb1, error error
error:
extend_lifetime %var <=== insert this
unreachable
This allows Span to depend on local unsafe pointers AND be used within
throwing closures:
_ = a.withUnsafeBufferPointer {
let buffer = $0
let view = Span(_unsafeElements: buffer)
return view.withUnsafeBufferPointer(\.count)
}
The reason why I am doing this is that in certain cases the AST captures indices
will never actually line up with partial apply capture indices since we seem to
"smush" together closures and locally defined functions.
NOTE: The reason for the really small amount of test changes is that this change
does not change the actual output by design. The only cases I had to change were
a case where we began to emit a better diagnostic and also where I added code
coverage around _ and let _ since those require ignored_use to be implemented so
that they would be diagnosed (previously we just did not emit anything so we
couldn't emit the diagnostic at the SIL level).
rdar://142661388
This is used for synthetic uses like _ = x that do not act as a true use but
instead only suppress unused variable warnings. This patch just adds the
instruction.
Eventually, we can use it to move the unused variable warning from Sema to SIL
slimmming the type checker down a little bit... but for now I am using it so
that other diagnostic passes can have a SIL instruction (with SIL location) so
that we can emit diagnostics on code like _ = x. Today we just do not emit
anything at all for that case so a diagnostic SIL pass would not see any
instruction that it could emit a diagnostic upon. In the next patch of this
series, I am going to add SILGen support to do that.
The newer version of clang will issue warnings in more cases,
specifically, -Winvalid-offsetof and -Wunused-but-set-variable.
This cleans up the new warnings issued from header, which shows up for
every TU that includes them. Fixing them should make the remaining
warnings easier to read.
Put AvailabilityRange into its own header with very few dependencies so that it
can be included freely in other headers that need to use it as a complete type.
NFC.
This attribute makes it so that a parameter of the annotated type, as well as
any type structurally containing that type as a field, becomes passed as
if `@_addressable` if the return value of the function has a dependency on
the parameter. This allows nonescapable values to take interior pointers into
such types.
And move the implementation of `SIL.Type.canBeClass` to the AST Type. The SIL Type just calls the AST Type implementation.
Also rename `SIL.Type.canonicalASTType` -> `SIL.Type.astType`.
C unions are imported as opaque types. Therefore we have to assume that a union contains a pointer.
This is important for alias analysis to catch escaping pointers via C unions.
Fixes a miscompile.
rdar://141555290