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::TupleExtractInst:
|
||||||
case ValueKind::StructExtractInst:
|
case ValueKind::StructExtractInst:
|
||||||
case ValueKind::OpenExistentialValueInst:
|
case ValueKind::OpenExistentialValueInst:
|
||||||
|
case ValueKind::OpenExistentialBoxValueInst:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return isOwnershipForwardingValueKind(K);
|
return isOwnershipForwardingValueKind(K);
|
||||||
@@ -467,6 +468,7 @@ NO_OPERAND_INST(KeyPath)
|
|||||||
}
|
}
|
||||||
CONSTANT_OWNERSHIP_INST(Guaranteed, MustBeLive, RefElementAddr)
|
CONSTANT_OWNERSHIP_INST(Guaranteed, MustBeLive, RefElementAddr)
|
||||||
CONSTANT_OWNERSHIP_INST(Guaranteed, MustBeLive, OpenExistentialValue)
|
CONSTANT_OWNERSHIP_INST(Guaranteed, MustBeLive, OpenExistentialValue)
|
||||||
|
CONSTANT_OWNERSHIP_INST(Guaranteed, MustBeLive, OpenExistentialBoxValue)
|
||||||
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, AutoreleaseValue)
|
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, AutoreleaseValue)
|
||||||
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, DeallocBox)
|
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, DeallocBox)
|
||||||
CONSTANT_OWNERSHIP_INST(Owned, MustBeInvalidated, DeallocExistentialBox)
|
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, CopyBlock)
|
||||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, DynamicMethod)
|
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, DynamicMethod)
|
||||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, OpenExistentialBox)
|
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, OpenExistentialBox)
|
||||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, OpenExistentialBoxValue)
|
|
||||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefTailAddr)
|
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefTailAddr)
|
||||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefToRawPointer)
|
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefToRawPointer)
|
||||||
ACCEPTS_ANY_NONTRIVIAL_OWNERSHIP(MustBeLive, RefToUnmanaged)
|
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
|
// without additional work, in SIL we require opened archetypes to
|
||||||
// be borrowed sub-objects of the parent CoW box.
|
// be borrowed sub-objects of the parent CoW box.
|
||||||
CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, OpenExistentialValue)
|
CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, OpenExistentialValue)
|
||||||
|
CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Guaranteed, OpenExistentialBoxValue)
|
||||||
CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Owned, UnconditionalCheckedCastValue)
|
CONSTANT_OR_TRIVIAL_OWNERSHIP_INST(Owned, UnconditionalCheckedCastValue)
|
||||||
|
|
||||||
// unchecked_bitwise_cast is a bitwise copy. It produces a trivial or unowned
|
// 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(ConvertFunction)
|
||||||
FORWARDING_OWNERSHIP_INST(InitExistentialRef)
|
FORWARDING_OWNERSHIP_INST(InitExistentialRef)
|
||||||
FORWARDING_OWNERSHIP_INST(OpenExistentialRef)
|
FORWARDING_OWNERSHIP_INST(OpenExistentialRef)
|
||||||
FORWARDING_OWNERSHIP_INST(OpenExistentialBoxValue)
|
|
||||||
FORWARDING_OWNERSHIP_INST(RefToBridgeObject)
|
FORWARDING_OWNERSHIP_INST(RefToBridgeObject)
|
||||||
FORWARDING_OWNERSHIP_INST(SelectValue)
|
FORWARDING_OWNERSHIP_INST(SelectValue)
|
||||||
FORWARDING_OWNERSHIP_INST(Object)
|
FORWARDING_OWNERSHIP_INST(Object)
|
||||||
|
|||||||
@@ -665,6 +665,15 @@ ManagedValue SILGenBuilder::createOpenExistentialValue(SILLocation loc,
|
|||||||
return ManagedValue::forUnmanaged(openedExistential);
|
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,
|
ManagedValue SILGenBuilder::createStore(SILLocation loc, ManagedValue value,
|
||||||
SILValue address,
|
SILValue address,
|
||||||
StoreOwnershipQualifier qualifier) {
|
StoreOwnershipQualifier qualifier) {
|
||||||
|
|||||||
@@ -284,6 +284,10 @@ public:
|
|||||||
ManagedValue createOpenExistentialValue(SILLocation loc,
|
ManagedValue createOpenExistentialValue(SILLocation loc,
|
||||||
ManagedValue original, SILType type);
|
ManagedValue original, SILType type);
|
||||||
|
|
||||||
|
using SILBuilder::createOpenExistentialBoxValue;
|
||||||
|
ManagedValue createOpenExistentialBoxValue(SILLocation loc,
|
||||||
|
ManagedValue original, SILType type);
|
||||||
|
|
||||||
using SILBuilder::createOptionalSome;
|
using SILBuilder::createOptionalSome;
|
||||||
ManagedValue createOptionalSome(SILLocation Loc, ManagedValue Arg);
|
ManagedValue createOptionalSome(SILLocation Loc, ManagedValue Arg);
|
||||||
ManagedValue createManagedOptionalNone(SILLocation Loc, SILType Type);
|
ManagedValue createManagedOptionalNone(SILLocation Loc, SILType Type);
|
||||||
|
|||||||
@@ -905,9 +905,8 @@ SILGenFunction::emitOpenExistential(
|
|||||||
loweredOpenedType));
|
loweredOpenedType));
|
||||||
} else {
|
} else {
|
||||||
assert(!silConv.useLoweredAddresses());
|
assert(!silConv.useLoweredAddresses());
|
||||||
archetypeMV = ManagedValue::forUnmanaged(
|
archetypeMV = getBuilder().createOpenExistentialBoxValue(
|
||||||
B.createOpenExistentialBoxValue(loc, existentialValue.getValue(),
|
loc, existentialValue, loweredOpenedType);
|
||||||
loweredOpenedType));
|
|
||||||
}
|
}
|
||||||
// NB: Don't forward the cleanup, because consuming a boxed value won't
|
// NB: Don't forward the cleanup, because consuming a boxed value won't
|
||||||
// consume the box reference.
|
// 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 -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
|
public typealias AnyObject = Builtin.AnyObject
|
||||||
|
|
||||||
precedencegroup CastingPrecedence {}
|
precedencegroup CastingPrecedence {}
|
||||||
|
precedencegroup AssignmentPrecedence {}
|
||||||
|
|
||||||
public protocol _ObjectiveCBridgeable {}
|
public protocol _ObjectiveCBridgeable {}
|
||||||
|
|
||||||
@@ -16,12 +18,12 @@ public protocol Decoder {
|
|||||||
|
|
||||||
// Test open_existential_value ownership
|
// 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: bb0(%0 : @owned $Decoder):
|
||||||
// CHECK: [[BORROW1:%.*]] = begin_borrow %0 : $Decoder
|
// CHECK: [[BORROW1:%.*]] = begin_borrow %0 : $Decoder
|
||||||
// CHECK: [[OPENED:%.*]] = open_existential_value [[BORROW1]] : $Decoder to $@opened("{{.*}}") 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: [[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 Builtin.NativeObject), normal bb2, error bb1
|
// 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:bb{{.*}}([[RET1:%.*]] : @owned $UnkeyedDecodingContainer):
|
||||||
// CHECK: end_borrow [[BORROW1]] from %0 : $Decoder, $Decoder
|
// 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)
|
#if os(OSX)
|
||||||
// Test open_existential_value used in a conversion context.
|
// 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 {
|
public func _unsafeDowncastToAnyObject(fromAny any: Any) -> AnyObject {
|
||||||
return any as AnyObject
|
return any as AnyObject
|
||||||
}
|
}
|
||||||
#endif
|
#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> {
|
public enum Optional<Wrapped> {
|
||||||
case none
|
case none
|
||||||
case some(Wrapped)
|
case some(Wrapped)
|
||||||
|
|||||||
Reference in New Issue
Block a user