Commit Graph

218 Commits

Author SHA1 Message Date
Joe Shajrawi
ca77872ba8 Merge CheckedCastValueBranch with new master 2017-03-06 17:32:09 -08:00
Joe Shajrawi
1f626304f1 Add support for conditional checked cast instruction for opaque value types + SILGen support for it 2017-03-06 16:35:27 -08:00
Michael Gottesman
cfb5893663 [silgen] Fix destroying destructor to use proper ownership with its @owned return value.
rdar://29791263
2017-03-02 17:17:17 -08:00
Michael Gottesman
4bc12aedbd [sil] Add end_lifetime.
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.
2017-03-01 18:30:23 -08:00
Michael Gottesman
455c126238 [semantic-sil] Pass the uncasted argument as an @owned arg in the failed checked_cast_br cast.
Previously, we would put a destroy_value directly on the value that we tried to
cast. Since checked_cast_br is consuming, this would cause the destroy_value on
the failure path to be flagged as a double consume.

This commit causes SILGen to emit the value consumed by checked_cast_br as an
@owned argument to the failure BB, allowing semantic arc rules to be respected.

As an additional benefit, I also upgraded the ownership_model_eliminator test to
use semantic sil verification.

One issue that did come up though is that I was unable to use the new code in
all locations in the compiler. Specifically, there is one location in
SILGenPattern that uses argument unforwarding. I am going to need to undo
argument unforwarding in SILGenPattern in order to completely eliminate the old
code path.
2017-02-28 17:29:03 -05:00
Joe Shajrawi
16b6cb5e1d Support for deinit of opaque existentials: deinit_existential_opaque instruction + SILGen support 2017-02-27 14:46:43 -08:00
Michael Gottesman
2a75a12fc7 Fix ownership classification of opaque instructions and re-enable opaque_values_silgen test. 2017-02-23 16:49:03 -08:00
Joe Shajrawi
ec1e3ee20e Add support for unconditional checked cast instruction for opaque value types + SILGen support for it 2017-02-22 16:35:46 -08:00
Joe Shajrawi
1e521c453b Add support for Init Existentials for opaque value types 2017-02-20 16:40:02 -08:00
practicalswift
8af31961b2 Merge pull request #7464 from practicalswift/gardening-20170214b
[gardening] Fix recently introduced typos
2017-02-14 21:10:52 +01:00
practicalswift
65b0219f7b [gardening] Fix typos 2017-02-14 20:04:08 +01:00
Michael Gottesman
9a136cfc1e [ownership-verifier] Teach the ownership verifier how to handle control dependent ownership from cond_br.
Rememebering that the verifier ensures that any edge that propagates ownership
along a cond_br can not be critical, we do this by sinking the use by the
cond_br into the destination blocks.

rdar://29791263
2017-02-14 11:03:29 -08:00
Michael Gottesman
ed67bf9f21 [ownership-verifier] Teach the ownership verifier how to handle unreachable code.
There are a few different use cases here:

1. In Raw SIL, no return folding may not have been run yet implying that a call
to a no-return function /can/ have arbitrary control flow after it (consider
mandatory inlined functions). We need to recognize that the region of code that
is strictly post dominated by the no-return function is "transitively
unreachable" and thus leaking is ok from that point. *Footnote 1*.

2. In Canonical and Raw SIL, we must recognize that unreachables and no-return
functions constitute places where we are allowed to leak.

rdar://29791263

----

*Footnote 1*: The reason why this is done is since we want to emit unreachable
code diagnostics when we run no-return folding. By leaving in the relevant code,
we have preserved all of the SILLocations on that code allowing us to create
really nice diagnostics.
2017-02-13 16:36:01 -08:00
Joe Shajrawi
df5297d877 Merge pull request #7349 from shajrawi/open_existential
Support for Open Existentials that do no take an address
2017-02-09 12:39:16 -08:00
Joe Shajrawi
c478828de7 Support for Open Existentials that do no take an address 2017-02-09 11:25:34 -08:00
Michael Gottesman
0bf0acd7f2 [ownership-verifier] Make unchecked_enum_data a propagating instruction.
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
2017-02-08 19:13:54 -08:00
Michael Gottesman
49506557e3 [sil] Change SILResultInfo::getOwnershipKind to always take a CanGenericSignature.
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
2017-02-08 16:43:38 -08:00
Michael Gottesman
07a71d0518 [ownership-verifier] Implement use checking for builtins.
I implemented the mapping from  SILValue -> ValueOwnershipKind for builtins a
long time ago, but did not implement the stub for what ValueOwnershipKind's can
be accepted by builtins. It is a pretty simple mapping (most things are
trivial).

The only interesting cases are:

1. ErrorInMain, UnexpectedError, WillThrow: These take in an @owned error
parameter, but are just normal uses of the value, not lifetime ending uses.

2. UnsafeGuaranteed. This is a bonafide actual +1 lifetime ending use. It is the
only one in the builtins.

rdar://29791263
2017-02-06 14:59:48 -08:00
Michael Gottesman
6a4368529d [ownership-verifier] Loosen the restrictions on mark_dependence since turns out we can also take a guaranteed argument as the value that is depended upon.
This occurs specifically, when our base is a class and we are performing a
materialize for set on a sub field of the class.

rdar://29791263
2017-02-06 12:58:01 -08:00
Michael Gottesman
9c47c305db [ownership-verifier] Allow for trivial cases of non-trivial enums to be passed as @owned, @unowned, and @guaranteed arguments.
The logic here is that a function argument can be viewed as a PHI node in the
program graph (i.e. cfg for each function + call graph). Just like with normal
PHI nodes, we need to treat enums passed into these PHI nodes as true sum types,
but at the same time, do not want to constrain optimization when we know that
the payloaded type is trivial.

rdar://29791263
2017-02-06 12:50:14 -08:00
Michael Gottesman
88dc60c2ff [ownership-verifier] ValueMetatype has a single argument that can be trivial or @owned... so just make it take anything.
rdar://29791263
2017-02-06 12:43:50 -08:00
Michael Gottesman
554feff463 [semantic-sil] Create unmanaged_autorelease_value.
This is an autorelease for use with Builtin.autorelease that does not need to be
balanced as part of the ownership model.

rdar://29791263
2017-02-06 12:11:46 -08:00
Michael Gottesman
dc8b994fc2 [silgen] ref_element_addr should always take a borrowed operand.
rdar://29791263
2017-02-06 11:45:49 -08:00
Michael Gottesman
0bea544c34 [ownership-verifier] alloc_value_buffer returns a trivial value... 2017-02-05 20:18:24 -08:00
Michael Gottesman
8d570fdfbf [ownership-verifier] existential_metatype can accept addresses as well as objects meaning it can accept also trivial ownership. 2017-02-05 20:18:24 -08:00
Michael Gottesman
7517391d86 [ownership-verifier] unchecked_trivial_bit_cast always produces trivial types, but accepts any type. 2017-02-05 20:18:24 -08:00
Michael Gottesman
88fc2fed6f [ownership-verifier] Another place I forgot to change getType().isTrivial(Mod) to a check against ValueOwnershipKind::Trivial.
This is needed to handle correctly:

1. non-trivial addresses.
2. trivial enum cases of enums that also have non-trivial payloaded cases.
2017-02-05 20:18:24 -08:00
Michael Gottesman
b0e4c68f61 [ownership-verifier] When we determine the OwnershipKind that select enum forwards, we should not look at the condition operand, just the case operands.
rdar://29791263
2017-02-05 20:18:24 -08:00
Slava Pestov
dca292c652 Serialization: Don't serialize contextual enum argument type
Storing this separately is unnecessary since we already
serialize the enum element's interface type. Also, this
eliminates one of the few remaining cases where we serialize
archetypes during AST serialization.
2017-01-30 00:08:53 -08:00
Michael Gottesman
10ad10e8bc [ownership-verifier] mark_uninitialized is a forwarding instruction, not always trivial.
This can be seen in the case of a [rootself] variable.

rdar://29791263
2017-01-26 16:46:42 -08:00
Andrew Trick
1abeddcc5d [SILType] SILFunctionConventions API.
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.
2017-01-26 15:35:48 -08:00
Michael Gottesman
e16f01529e [ownership-verifier] Until we agree on a list of uses that are considered as preserving the lifetime of a mark_dependence, just propagate the mark_dependence into the use set of the base rather than the uses of the value.
rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
a9fcfcb272 [ownership-verifier] When verifying forwarded values, make sure to ignore
trivial ownership in aggregates that are non-trivial.

rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
74fc8d9067 [ownership-verifier] Allow for trivial enum args to be passed into non-trivial phi nodes.
rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
659a93ba99 [ownership-verifier] alloc_ref, alloc_ref_dynamic can have trivial arguments for tail stored data.
rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
ad9cd2ade1 [ownership-verifier] project_existential_box takes a non-trivial existential argument, not a trivial argument.
rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
cf7e480765 [ownership-verifier] Throw takes in an Error parameter which is an @owned protocol.
rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
1ef8ea6bc1 [ownership-verifier] alloc_value_buffer/dealloc_value_buffer have single trivial address operands.
rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
7476f16a00 [ownership-verifier] Forwarding instructions only are lifetime ending uses when forwarding owned semantics.
rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
c7aa4e294e [ownership-verifier] We accept owned/guaranteed/unowned in unowned positions.
Unowned is a +0 convention that requires the user to "copy" the relevant value
before any side effects occur in the callee. This means that it is safe to pass
owned/guaranteed/unowned to such functions.

rdar://29791263
2017-01-25 18:03:05 -08:00
Michael Gottesman
f78ffdb941 [ownership-verifier] Ignore type dependent operands when checking for uses since we don't care about them.
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
2017-01-25 18:03:05 -08:00
Michael Gottesman
4c7ec6e4dd [ownership-verifier] switch_enum, checked_cast_br, dynamic_method_br can have trivial and owned operands.
In the case of switch_enum this is just trivial enums. In the case of
checked_cast_br and dynamic_method_br, the potential trivial arguments are
metatypes.

rdar://29791263
2017-01-24 19:38:38 -08:00
Michael Gottesman
adb85df969 [ownership-verifier] Use a check against ValueOwnershipKind::Trivial instead of SILType::isTrivial to determine trivial ownership in isValueAddressOrTrivial.
Without this enums with non-trivial cases are always treated as non-trivial even
if a just created enum is trivial. For example the following no payload enum
would be considered non-trivial.

    %0 = enum $Optional<Builtin.NativeObject>, #Optional.none!enumelt

rdar://29791263
2017-01-24 18:11:02 -08:00
Michael Gottesman
e8ede8b32c [ownership-verifier] We should always stop at the dominating block definition when verifying.
I think this was introduced relatively recently. I added a test so that it does
not happen again.

rdar://29791263
2017-01-24 16:43:27 -08:00
Michael Gottesman
e826d431a9 [ownership-verifier] When verifying a def that is immediately consumed in the same block, do not add the block's predecessors to the worklist for visiting purposes.
rdar://29791263
2017-01-24 16:40:10 -08:00
Michael Gottesman
0a4618e93e [semantic-sil] Implement parsing and printing of ownership attributes on SILArguments.
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
2017-01-22 22:02:31 -08:00
Michael Gottesman
d045f20867 [semantic-sil] Add a new instruction end_borrow_argument.
I need this instruction in order to model the end of life of a guaranteed phi
arguments.

rdar://29791263
2017-01-22 20:46:25 -08:00
Michael Gottesman
f857f2c6bf [ownership-verifier] Add proper subobject borrowing verification.
Previously, we would require an end_borrow for guaranteed subobject borrows.
This was not the end design and of course would have triggered asserts since
end_borrow only supports ending borrows of the same type (by design). This
commit finishes the design by:

1. Verifying that subobject borrows do not have an end_borrow. This is done by
asserting that subobject borrows do not have lifetime ending uses.

2. Treating uses of a subobject borrow as normal liveness uses of the base
borrowed object. This means that the verifier will assert if there are
any uses of borrowed subobjects after the base's end_value.

rdar://29791263
2017-01-21 23:54:33 -08:00
Michael Gottesman
f462d201ab [ownership-verifier] Rename PrintMessageInsteadOfAssert => IsSILOwnershipVerifierTestingEnabled and use it to disable SILInstruction::verifyOperandOwnership
The method SILInstruction::verifyOperandOwnership() is used in SILBuilder to
ensure that as instructions are created, if there are any use failures, the
error is caught at the moment the instruction is created. This makes debugging
such failures trivial. *NOTE* This does not cause dataflow verification to
occur.

The problem is that when PrintMessageInsteadOfAssert is enabled, this causes
dataflow failures to have their error messages emitted twice, complicating
FileCheck testing of the verifier.

Thus, this commit disables SILInstruction::verifyOperandOwnership() when
PrintMessageInsteadOfAssert is enabled. PrintMessageInsteadOfAssert is renamed
to 'IsSILOwnershipVerifierTestingEnabled' in light of its expanded role.

rdar://29791263
2017-01-21 23:54:33 -08:00
Michael Gottesman
df69ada2c1 [semantic-sil] Improve output for FileCheck tests for ownership verifier by printing out the function name first.
This just standardizes the output.

rdar://29791263
2017-01-20 11:52:34 -08:00