Introduce a new runtime entry point,
`swift_objc_swift3ImplicitObjCEntrypoint`, which is called from any
Objective-C method that was generated due to `@objc` inference rules
that were removed by SE-0160. Aside from being a central place where
users can set a breakpoint to catch when this occurs, this operation
provides logging capabilities that can be enabled by setting the
environment variable SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT:
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=0 (default): do not log
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=1: log failed messages
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=2: log failed messages with
backtrace
SWIFT_DEBUG_IMPLICIT_OBJC_ENTRYPOINT=3: log failed messages with
backtrace and abort the process.
The log messages look something like:
***Swift runtime: entrypoint -[t.MyClass foo] generated by
implicit @objc inference is deprecated and will be removed in
Swift 4
Previously often times when casting a value, we would just pass along the
cleanup of the uncasted value. With semantic SIL this is no longer correct since
the cleanup now needs to be on the cast result.
This caused problems for certain usages of Builtin.castToNativeObject(...) by
the stdlib. Specifically, the stdlib was using this on AnyObject values that
were not necessarily native. Since we were recreating the cleanup on the native
value, a swift native release was being used =><=.
In this commit I solve this problem by:
1. Adding an assert in Builtin.castToNativeObject(...) that ensures that any value
passed to Builtin.castToNativeObject() is known conservatively to use swift
native reference counting.
2. I changed all uses where we do not have a precondition of a native ref
counting type to use Builtin.castToUnknownObject(...).
3. I added a new Builtin called Builtin.unsafeCastToNativeObject(...) that does
not have the compile time check. I used this to rewrite callsites in the stdlib
where we know via preconditions that an AnyObject will dynamically always be
native.
rdar://29791263
...and IRGen it into a call to __tsan_write1 in compiler-rt. This is
preparatory work for a later patch that will add an experimental
option to treat Swift inout accesses as TSan writes.
This is the lifetime ending variant of fix_lifetime. It is a lie to the
ownership verifier that a value is being consumed along a path. Its intention is
to be used to allow for the static verification of ownership in deallocating
deinits which for compatibility with objective-c have weird ownership behavior.
See the commit merged with this commit for more information.
This allows for an unchecked_enum_data to be either a consumed instruction or a
borrowed instruction. The reason why this makes sense in contrast to other value
projection operations like struct_extract and tuple_extract is that an enum
payload is essentially a tuple. This means that we are extracting the entire
value when we perform a struct_extract. So forwarding is viable from a semantic
perspective since if we destroy the payload, there is nothing left to destroy.
This contrasts with struct_extract and tuple_extract where we may have other
parts of the struct/tuple to destroy.
rdar://29791263
This caused a crasher when running the ownership verifier. I don't have a test
case right now, since it happened several weeks ago.
The bug can not happen again since I eliminated the nullptr default argument.
rdar://29791263
I thought this was modeling a value returned at +0. But in reality, the
instruction is created a guaranteed region by performing the following
instruction sequence:
%1 = copy_value %0 : $GuaranteedValue
(%2, %3) = Builtin "unsafeGuaranteed" (%1)
... *STUFF* ...
Builtin "endUnsafeGuaranteed" (%2) : $Token
destroy_value %3 : $GuaranteedValue
rdar://29791263
[NFC] Add -enable-sil-opaque-values frontend option.
This will be used to change the SIL-level calling convention for opaque values,
such as generics and resilient structs, to pass-by-value. Under this flag,
opaque values have SSA lifetimes, managed by copy_value and destroy_value.
This will make it easier to optimize copies and verify ownership.
* [SILGen] type lowering support for opaque values.
Add OpaqueValueTypeLowering.
Under EnableSILOpaqueValues, lower address-only types as opaque values.
* [SIL] Fix ValueOwnershipKind to support opaque SIL values.
* Test case: SILGen opaque value support for Parameter/ResultConvention.
* [SILGen] opaque value support for function arguments.
* Future Test case: SILGen opaque value specialDest arguments.
* Future Test case: SILGen opaque values: emitOpenExistential.
* Test case: SIL parsing support for EnableSILOpaqueValues.
* SILGen opaque values: prepareArchetypeCallee.
* [SIL Verify] allow copy_value for EnableSILOpaqueValues.
* Test cast: SIL serializer support for opaque values.
* Add a static_assert for ParameterConvention layout.
* Test case: Mandatory SILOpt support for EnableSILOpaqueValues.
* Test case: SILOpt support for EnableSILOpaqueValues.
* SILGen opaque values: TypeLowering emitCopyValue.
* SILBuilder createLoad. Allow loading opaque values.
* SIL Verifier. Allow loading and storing opaque values.
* SILGen emitSemanticStore support for opaque values.
* Test case for SILGen emitSemanticStore.
* Test case for SIL mandatory support for inout assignment.
* Fix SILGen opaque values test case after rebasing.
Separate formal lowered types from SIL types.
The SIL type of an argument will depend on the SIL module's conventions.
The module conventions are determined by the SIL stage and LangOpts.
Almost NFC, but specialized manglings are broken incidentally as a result of
fixes to the way passes handle book-keeping of aruments. The mangler is fixed in
the subsequent commit.
Otherwise, NFC is intended, but quite possible do to rewriting the logic in many
places.
This also avoids undefined behavior when we try to look up the
ParameterConvention of a type dependent operand. Since type dependent operands
do not have a convention, this causes us to hit an assertion.
rdar://29791263
This is only enabled when semantic sil is enabled /and/ we are not parsing
unqualified SIL.
*NOTE* To properly write tests for this, I had to rework how we verified
Branch/CondBranch insts to be actually correct (instead of pseudo-correct). I
have to put this functionality together in order to write tests.
rdar://29791263
The reason why I am introducing special instructions is so I can maintain the
qualified ownership API wedge in between qualified SIL and the rest of the ARC
instructions that are pervasively used in the compiler.
These instructions in the future /could/ be extended to just take @sil_unmanaged
operands directly, but I want to maintain flexibility to take regular
non-trivial operands in the short term.
rdar://29791263
Originally, we were going to use the result to enforce end_borrow lifetimes for
store_borrow. But with Andy's changes, this should no longer be necessary since
@in_guaranteed and @guaranteed will both take values.
rdar://29791263
The way SILResultInfo::getOwnershipKind(SILModule &) was implemented before was
incorrect, resulting in getTypeLowering being called on a lowered type without a
proper generic signature being pushed on the type lowering stack. This commit
fixes that issue locally.
The real fix is in a PR that Slava is preparing that provides a getTypeLowering
that takes a SILType and a GenericSignature so that the user does not need to
perform a push/pop.
rdar://29791263
Metatypes in SIL are trivial, until we conver them to objects (mainly for cases
where one converts the metatype to an object for use in objc). Thus these
conversion functions must be treated as returning an @owned value.
This is used in SILGen in a few different cases:
1. trivial -> non-trivial. This should have unowned semantics since one should
retain before use.
2. non-trivial -> trivial. This should have trivial semantics.
3. trivial -> trivial. This should have trivial semantics.
4. non-trivial -> non-trivial. This should have forwarding semantics.
This is the first verifier for SemanticSIL. The verifier is very simple and
verifies that given a SILValue V, V->getOwnershipKind() returns an ownership
kind compatible with all of V's user instructions.
This is implemented by adding a new method to SILInstruction:
SILInstruction::verifyOperandOwnership()
This method creates an instance of the visitor OwnershipCompatibilityUseChecker
and then has the instance visit this.
The OwnershipCompatibilityUseChecker is a SILInstructionVisitor that for a given
instruction verifies that the given SILInstruction's operand SILValue's produce
ValueOwnershipKind that are compatible with the SILInstruction. The reason why
it is implemented as a visitor is to ensure that a warning is produced if a new
instruction is added and a method on the OwnershipCompatibleUseChecker isn't
added.
Keep in mind that this is just the first verifier and the full verifier (that
also verifies dataflow) is built on top of it. The reason why this separate API
to the use verifier is exposed is that exposing the checker enables us to place
an assert in SILBuilder to diagnose any places where SIL ownership is violated
immediately when the violation occurs allowing for an easy debugging experience
for compiler writers. This assert is a key tool that I am going to be using to
make SILGen conform to the SIL Ownership Model.
Again, this will be behind the -enable-semantic-sil flag, so normal development
will be unaffected by this change.
rdar://29671437
We preserve the current behavior of assuming Any ownership always and use
default arguments to hide this change most of the time. There are asserts now in
the SILBasicBlock::{create,replace,insert}{PHI,Function}Argument to ensure that
the people can only create SILFunctionArguments in entry blocks and
SILPHIArguments in non-entry blocks. This will ensure that the code in tree
maintains the API distinction even if we are not using the full distinction in
between the two.
Once the verifier is finished being upstreamed, I am going to audit the
createPHIArgument cases for the proper ownership. This is b/c I will be able to
use the verifier to properly debug the code. At that point, I will also start
serializing/printing/parsing the ownershipkind of SILPHIArguments, but lets take
things one step at a time and move incrementally.
In the process, I also discovered a CSE bug. I am not sure how it ever worked.
Basically we replace an argument with a new argument type but return the uses of
the old argument to refer to the old argument instead of a new argument.
rdar://29671437