mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[sil-opaque-values] Fix SILGen and ownership of open_existential_box_value.
This commit is contained in:
@@ -221,6 +221,7 @@ static bool isGuaranteedForwardingValueKind(ValueKind K) {
|
||||
case ValueKind::TupleExtractInst:
|
||||
case ValueKind::StructExtractInst:
|
||||
case ValueKind::OpenExistentialValueInst:
|
||||
case ValueKind::OpenExistentialBoxValueInst:
|
||||
return true;
|
||||
default:
|
||||
return isOwnershipForwardingValueKind(K);
|
||||
@@ -467,6 +468,7 @@ NO_OPERAND_INST(KeyPath)
|
||||
}
|
||||
CONSTANT_OWNERSHIP_INST(Guaranteed, MustBeLive, RefElementAddr)
|
||||
CONSTANT_OWNERSHIP_INST(Guaranteed, MustBeLive, OpenExistentialValue)
|
||||
CONSTANT_OWNERSHIP_INST(Guaranteed, MustBeLive, OpenExistentialBoxValue)
|
||||
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, AutoreleaseValue)
|
||||
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, DeallocBox)
|
||||
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, DeallocExistentialBox)
|
||||
@@ -613,7 +615,6 @@ ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, BridgeObjectToWord)
|
||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, CopyBlock)
|
||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, DynamicMethod)
|
||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, OpenExistentialBox)
|
||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, OpenExistentialBoxValue)
|
||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefTailAddr)
|
||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefToRawPointer)
|
||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefToUnmanaged)
|
||||
|
||||
@@ -139,6 +139,7 @@ CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, TupleExtract)
|
||||
// without additional work, in SIL we require opened archetypes to
|
||||
// be borrowed sub-objects of the parent CoW box.
|
||||
CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, OpenExistentialValue)
|
||||
CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, OpenExistentialBoxValue)
|
||||
CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Owned, UnconditionalCheckedCastValue)
|
||||
|
||||
// unchecked_bitwise_cast is a bitwise copy. It produces a trivial or unowned
|
||||
@@ -287,7 +288,6 @@ FORWARDING_OWNERSHIP_INST(BridgeObjectToRef)
|
||||
FORWARDING_OWNERSHIP_INST(ConvertFunction)
|
||||
FORWARDING_OWNERSHIP_INST(InitExistentialRef)
|
||||
FORWARDING_OWNERSHIP_INST(OpenExistentialRef)
|
||||
FORWARDING_OWNERSHIP_INST(OpenExistentialBoxValue)
|
||||
FORWARDING_OWNERSHIP_INST(RefToBridgeObject)
|
||||
FORWARDING_OWNERSHIP_INST(SelectValue)
|
||||
FORWARDING_OWNERSHIP_INST(Object)
|
||||
|
||||
@@ -665,6 +665,15 @@ ManagedValue SILGenBuilder::createOpenExistentialValue(SILLocation loc,
|
||||
return ManagedValue::forUnmanaged(openedExistential);
|
||||
}
|
||||
|
||||
ManagedValue SILGenBuilder::createOpenExistentialBoxValue(SILLocation loc,
|
||||
ManagedValue original,
|
||||
SILType type) {
|
||||
ManagedValue borrowedExistential = original.borrow(SGF, loc);
|
||||
SILValue openedExistential = SILBuilder::createOpenExistentialBoxValue(
|
||||
loc, borrowedExistential.getValue(), type);
|
||||
return ManagedValue::forUnmanaged(openedExistential);
|
||||
}
|
||||
|
||||
ManagedValue SILGenBuilder::createStore(SILLocation loc, ManagedValue value,
|
||||
SILValue address,
|
||||
StoreOwnershipQualifier qualifier) {
|
||||
|
||||
@@ -284,6 +284,10 @@ public:
|
||||
ManagedValue createOpenExistentialValue(SILLocation loc,
|
||||
ManagedValue original, SILType type);
|
||||
|
||||
using SILBuilder::createOpenExistentialBoxValue;
|
||||
ManagedValue createOpenExistentialBoxValue(SILLocation loc,
|
||||
ManagedValue original, SILType type);
|
||||
|
||||
using SILBuilder::createOptionalSome;
|
||||
ManagedValue createOptionalSome(SILLocation Loc, ManagedValue Arg);
|
||||
ManagedValue createManagedOptionalNone(SILLocation Loc, SILType Type);
|
||||
|
||||
@@ -905,9 +905,8 @@ SILGenFunction::emitOpenExistential(
|
||||
loweredOpenedType));
|
||||
} else {
|
||||
assert(!silConv.useLoweredAddresses());
|
||||
archetypeMV = ManagedValue::forUnmanaged(
|
||||
B.createOpenExistentialBoxValue(loc, existentialValue.getValue(),
|
||||
loweredOpenedType));
|
||||
archetypeMV = getBuilder().createOpenExistentialBoxValue(
|
||||
loc, existentialValue, loweredOpenedType);
|
||||
}
|
||||
// NB: Don't forward the cleanup, because consuming a boxed value won't
|
||||
// consume the box reference.
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// RUN: %target-swift-frontend -enable-sil-opaque-values -enable-sil-ownership -emit-sorted-sil -Xllvm -sil-full-demangle -emit-silgen -parse-stdlib -parse-as-library -module-name Swift %s | %FileCheck %s
|
||||
// RUN: %target-swift-frontend -target x86_64-apple-macosx10.9 -enable-sil-opaque-values -enable-sil-ownership -emit-sorted-sil -Xllvm -sil-full-demangle -emit-silgen -parse-stdlib -parse-as-library -module-name Swift %s | %FileCheck --check-prefix=CHECK-OSX %s
|
||||
|
||||
public typealias AnyObject = Builtin.AnyObject
|
||||
|
||||
precedencegroup CastingPrecedence {}
|
||||
precedencegroup AssignmentPrecedence {}
|
||||
|
||||
public protocol _ObjectiveCBridgeable {}
|
||||
|
||||
@@ -16,12 +18,12 @@ public protocol Decoder {
|
||||
|
||||
// Test open_existential_value ownership
|
||||
// ---
|
||||
// CHECK-LABEL: sil @_T0s11takeDecoderBi1_s0B0_p4from_tKF : $@convention(thin) (@in Decoder) -> (Builtin.Int1, @error Builtin.NativeObject) {
|
||||
// CHECK-LABEL: sil @_T0s11takeDecoderBi1_s0B0_p4from_tKF : $@convention(thin) (@in Decoder) -> (Builtin.Int1, @error Error) {
|
||||
// CHECK: bb0(%0 : @owned $Decoder):
|
||||
// CHECK: [[BORROW1:%.*]] = begin_borrow %0 : $Decoder
|
||||
// CHECK: [[OPENED:%.*]] = open_existential_value [[BORROW1]] : $Decoder to $@opened("{{.*}}") Decoder
|
||||
// CHECK: [[WT:%.*]] = witness_method $@opened("{{.*}}") Decoder, #Decoder.unkeyedContainer!1 : <Self where Self : Decoder> (Self) -> () throws -> UnkeyedDecodingContainer, %4 : $@opened("{{.*}}") Decoder : $@convention(witness_method) <τ_0_0 where τ_0_0 : Decoder> (@in_guaranteed τ_0_0) -> (@out UnkeyedDecodingContainer, @error Builtin.NativeObject)
|
||||
// CHECK: try_apply [[WT]]<@opened("{{.*}}") Decoder>([[OPENED]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Decoder> (@in_guaranteed τ_0_0) -> (@out UnkeyedDecodingContainer, @error Builtin.NativeObject), normal bb2, error bb1
|
||||
// CHECK: [[WT:%.*]] = witness_method $@opened("{{.*}}") Decoder, #Decoder.unkeyedContainer!1 : <Self where Self : Decoder> (Self) -> () throws -> UnkeyedDecodingContainer, %4 : $@opened("{{.*}}") Decoder : $@convention(witness_method) <τ_0_0 where τ_0_0 : Decoder> (@in_guaranteed τ_0_0) -> (@out UnkeyedDecodingContainer, @error Error)
|
||||
// CHECK: try_apply [[WT]]<@opened("{{.*}}") Decoder>([[OPENED]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Decoder> (@in_guaranteed τ_0_0) -> (@out UnkeyedDecodingContainer, @error Error), normal bb2, error bb1
|
||||
//
|
||||
// CHECK:bb{{.*}}([[RET1:%.*]] : @owned $UnkeyedDecodingContainer):
|
||||
// CHECK: end_borrow [[BORROW1]] from %0 : $Decoder, $Decoder
|
||||
@@ -58,13 +60,47 @@ public func unsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
|
||||
|
||||
#if os(OSX)
|
||||
// Test open_existential_value used in a conversion context.
|
||||
// (the actual bridging call is dropped because we don't import Swift).
|
||||
// ---
|
||||
//
|
||||
// CHECK-OSX-LABEL: sil @_T0s26_unsafeDowncastToAnyObjectyXlyp04fromD0_tF : $@convention(thin) (@in Any) -> @owned AnyObject {
|
||||
// CHECK-OSX: bb0(%0 : @owned $Any):
|
||||
// CHECK-OSX: [[BORROW:%.*]] = begin_borrow %0 : $Any
|
||||
// CHECK-OSX: [[COPY:%.*]] = copy_value [[BORROW]] : $Any
|
||||
// CHECK-OSX: [[BORROW2:%.*]] = begin_borrow [[COPY]] : $Any
|
||||
// CHECK-OSX: [[VAL:%.*]] = open_existential_value [[BORROW2]] : $Any to $@opened
|
||||
// CHECK-OSX: [[COPY2:%.*]] = copy_value [[VAL]] : $@opened
|
||||
// CHECK-OSX: destroy_value [[COPY2]] : $@opened
|
||||
// CHECK-OSX: end_borrow [[BORROW2]] from [[COPY]] : $Any, $Any
|
||||
// CHECK-OSX: destroy_value [[COPY]] : $Any
|
||||
// CHECK-OSX: end_borrow [[BORROW]] from %0 : $Any, $Any
|
||||
// CHECK-OSX: destroy_value %0 : $Any
|
||||
// CHECK-OSX: return undef : $AnyObject
|
||||
// CHECK-OSX-LABEL: } // end sil function '_T0s26_unsafeDowncastToAnyObjectyXlyp04fromD0_tF'
|
||||
public func _unsafeDowncastToAnyObject(fromAny any: Any) -> AnyObject {
|
||||
return any as AnyObject
|
||||
}
|
||||
#endif
|
||||
|
||||
public protocol Error {}
|
||||
|
||||
#if os(OSX)
|
||||
// Test open_existential_box_value in a conversion context.
|
||||
// ---
|
||||
// CHECK-OSX-LABEL: sil @_T0s3fooys5Error_pSg1e_tF : $@convention(thin) (@owned Optional<Error>) -> () {
|
||||
// CHECK-OSX: [[BORROW:%.*]] = begin_borrow %{{.*}} : $Error
|
||||
// CHECK-OSX: [[VAL:%.*]] = open_existential_box_value [[BORROW]] : $Error to $@opened
|
||||
// CHECK-OSX: [[COPY:%.*]] = copy_value [[VAL]] : $@opened
|
||||
// CHECK-OSX: [[ANY:%.*]] = init_existential_value [[COPY]] : $@opened
|
||||
// CHECK-OSX: end_borrow [[BORROW]] from %{{.*}} : $Error, $Error
|
||||
// CHECK-OSX-LABEL: } // end sil function '_T0s3fooys5Error_pSg1e_tF'
|
||||
public func foo(e: Error?) {
|
||||
if let u = e {
|
||||
let a: Any = u
|
||||
_ = a
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public enum Optional<Wrapped> {
|
||||
case none
|
||||
case some(Wrapped)
|
||||
|
||||
Reference in New Issue
Block a user