mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
ManualOwnership: provide ability to apply to entire compilation unit
With this patch, I'm flipping the polarity of things. The flag `-enable-experimental-feature ManualOwnership` now turns on the diagnostics, but they're all silenced by default. So, you need to add -Wwarning or -Werror to your build settings to turn on the specific diagnostics you care about. These are the diagnostic groups relevant to the feature: - SemanticCopies aka "explicit copies mode" - DynamicExclusivity For example, the build setting `-Werror SemanticCopies` now gives you errors about explicit copies, just as before, but now you can make them just warnings with -Wwarning. To opt-out a declaration from everything when using the feature, use @_noManualOwnership. @_manualOwnership is no longer an attribute as a result. resolves rdar://163372569
This commit is contained in:
@@ -815,7 +815,7 @@ SIMPLE_DECL_ATTR(_noObjCBridging, NoObjCBridging,
|
|||||||
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
|
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
|
||||||
155)
|
155)
|
||||||
|
|
||||||
SIMPLE_DECL_ATTR(_manualOwnership, ManualOwnership,
|
SIMPLE_DECL_ATTR(_noManualOwnership, NoManualOwnership,
|
||||||
OnAbstractFunction | OnSubscript,
|
OnAbstractFunction | OnSubscript,
|
||||||
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
|
UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
|
||||||
156)
|
156)
|
||||||
|
|||||||
@@ -2145,9 +2145,7 @@ ERROR(attr_static_exclusive_only_mutating,none,
|
|||||||
ERROR(attr_static_exclusive_no_setters,none,
|
ERROR(attr_static_exclusive_no_setters,none,
|
||||||
"variable of type %0 must not have a setter", (Type))
|
"variable of type %0 must not have a setter", (Type))
|
||||||
|
|
||||||
// @_manualOwnership
|
// ManualOwnership
|
||||||
ERROR(attr_manual_ownership_experimental,none,
|
|
||||||
"'@_manualOwnership' requires '-enable-experimental-feature ManualOwnership'", ())
|
|
||||||
ERROR(attr_manual_ownership_noimplicitcopy,none,
|
ERROR(attr_manual_ownership_noimplicitcopy,none,
|
||||||
"'@_noImplicitCopy' cannot be used with ManualOwnership", ())
|
"'@_noImplicitCopy' cannot be used with ManualOwnership", ())
|
||||||
|
|
||||||
|
|||||||
@@ -449,7 +449,9 @@ EXPERIMENTAL_FEATURE(LifetimeDependence, true)
|
|||||||
/// Enable the `@_staticExclusiveOnly` attribute.
|
/// Enable the `@_staticExclusiveOnly` attribute.
|
||||||
EXPERIMENTAL_FEATURE(StaticExclusiveOnly, true)
|
EXPERIMENTAL_FEATURE(StaticExclusiveOnly, true)
|
||||||
|
|
||||||
/// Enable the `@_manualOwnership` attribute.
|
/// Enable the ManualOwnership diagnostic groups:
|
||||||
|
/// * -Wwarning SemanticCopies
|
||||||
|
/// * -Wwarning DynamicExclusivity
|
||||||
EXPERIMENTAL_FEATURE(ManualOwnership, false)
|
EXPERIMENTAL_FEATURE(ManualOwnership, false)
|
||||||
|
|
||||||
/// Enable the @extractConstantsFromMembers attribute.
|
/// Enable the @extractConstantsFromMembers attribute.
|
||||||
|
|||||||
@@ -5024,7 +5024,7 @@ public:
|
|||||||
TRIVIAL_ATTR_PRINTER(NoLocks, no_locks)
|
TRIVIAL_ATTR_PRINTER(NoLocks, no_locks)
|
||||||
TRIVIAL_ATTR_PRINTER(NoMetadata, no_metadata)
|
TRIVIAL_ATTR_PRINTER(NoMetadata, no_metadata)
|
||||||
TRIVIAL_ATTR_PRINTER(NoObjCBridging, no_objc_bridging)
|
TRIVIAL_ATTR_PRINTER(NoObjCBridging, no_objc_bridging)
|
||||||
TRIVIAL_ATTR_PRINTER(ManualOwnership, manual_ownership)
|
TRIVIAL_ATTR_PRINTER(NoManualOwnership, no_manual_ownership)
|
||||||
TRIVIAL_ATTR_PRINTER(NoRuntime, no_runtime)
|
TRIVIAL_ATTR_PRINTER(NoRuntime, no_runtime)
|
||||||
TRIVIAL_ATTR_PRINTER(NonEphemeral, non_ephemeral)
|
TRIVIAL_ATTR_PRINTER(NonEphemeral, non_ephemeral)
|
||||||
TRIVIAL_ATTR_PRINTER(NonEscapable, non_escapable)
|
TRIVIAL_ATTR_PRINTER(NonEscapable, non_escapable)
|
||||||
|
|||||||
@@ -265,7 +265,6 @@ extension ASTGenVisitor {
|
|||||||
.LexicalLifetimes,
|
.LexicalLifetimes,
|
||||||
.LLDBDebuggerFunction,
|
.LLDBDebuggerFunction,
|
||||||
.MainType,
|
.MainType,
|
||||||
.ManualOwnership,
|
|
||||||
.Marker,
|
.Marker,
|
||||||
.MoveOnly,
|
.MoveOnly,
|
||||||
.NeverEmitIntoClient,
|
.NeverEmitIntoClient,
|
||||||
@@ -276,6 +275,7 @@ extension ASTGenVisitor {
|
|||||||
.NoRuntime,
|
.NoRuntime,
|
||||||
.NoImplicitCopy,
|
.NoImplicitCopy,
|
||||||
.NoLocks,
|
.NoLocks,
|
||||||
|
.NoManualOwnership,
|
||||||
.NoMetadata,
|
.NoMetadata,
|
||||||
.NoObjCBridging,
|
.NoObjCBridging,
|
||||||
.NonEphemeral,
|
.NonEphemeral,
|
||||||
|
|||||||
@@ -208,7 +208,9 @@ void SILFunctionBuilder::addFunctionAttributes(
|
|||||||
F->setPerfConstraints(PerformanceConstraints::NoExistentials);
|
F->setPerfConstraints(PerformanceConstraints::NoExistentials);
|
||||||
} else if (Attrs.hasAttribute<NoObjCBridgingAttr>()) {
|
} else if (Attrs.hasAttribute<NoObjCBridgingAttr>()) {
|
||||||
F->setPerfConstraints(PerformanceConstraints::NoObjCBridging);
|
F->setPerfConstraints(PerformanceConstraints::NoObjCBridging);
|
||||||
} else if (Attrs.hasAttribute<ManualOwnershipAttr>()) {
|
} else if (M.getASTContext().LangOpts.hasFeature(Feature::ManualOwnership) &&
|
||||||
|
constant && constant.hasDecl() && !constant.isImplicit() &&
|
||||||
|
!Attrs.hasAttribute<NoManualOwnershipAttr>()) {
|
||||||
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
|
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1368,15 +1368,15 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
|
|||||||
//
|
//
|
||||||
// If ManualOwnership ends up subsuming those prior mechanisms for an
|
// If ManualOwnership ends up subsuming those prior mechanisms for an
|
||||||
// explicit-copy mode, we can move this somewhere else, like postEmitFunction.
|
// explicit-copy mode, we can move this somewhere else, like postEmitFunction.
|
||||||
if (auto *ace = constant.getAbstractClosureExpr()) {
|
//
|
||||||
if (auto *dc = ace->getOutermostFunctionContext()) {
|
// FIXME: maybe this should happen in SILFunctionBuilder::getOrCreateFunction
|
||||||
if (auto *decl = dc->getAsDecl()) {
|
if (getASTContext().LangOpts.hasFeature(Feature::ManualOwnership))
|
||||||
if (decl->getAttrs().hasAttribute<ManualOwnershipAttr>()) {
|
if (auto *ace = constant.getAbstractClosureExpr())
|
||||||
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
|
if (auto *dc = ace->getOutermostFunctionContext())
|
||||||
}
|
if (auto *decl = dc->getAsDecl())
|
||||||
}
|
if (!decl->isImplicit() &&
|
||||||
}
|
!decl->getAttrs().hasAttribute<NoManualOwnershipAttr>())
|
||||||
}
|
F->setPerfConstraints(PerformanceConstraints::ManualOwnership);
|
||||||
|
|
||||||
LLVM_DEBUG(llvm::dbgs() << "lowering ";
|
LLVM_DEBUG(llvm::dbgs() << "lowering ";
|
||||||
F->printName(llvm::dbgs());
|
F->printName(llvm::dbgs());
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ public:
|
|||||||
IGNORED_ATTR(NoAllocation)
|
IGNORED_ATTR(NoAllocation)
|
||||||
IGNORED_ATTR(NoRuntime)
|
IGNORED_ATTR(NoRuntime)
|
||||||
IGNORED_ATTR(NoExistentials)
|
IGNORED_ATTR(NoExistentials)
|
||||||
|
IGNORED_ATTR(NoManualOwnership)
|
||||||
IGNORED_ATTR(NoObjCBridging)
|
IGNORED_ATTR(NoObjCBridging)
|
||||||
IGNORED_ATTR(EmitAssemblyVisionRemarks)
|
IGNORED_ATTR(EmitAssemblyVisionRemarks)
|
||||||
IGNORED_ATTR(ShowInInterface)
|
IGNORED_ATTR(ShowInInterface)
|
||||||
@@ -476,7 +477,6 @@ public:
|
|||||||
void visitUnsafeNonEscapableResultAttr(UnsafeNonEscapableResultAttr *attr);
|
void visitUnsafeNonEscapableResultAttr(UnsafeNonEscapableResultAttr *attr);
|
||||||
|
|
||||||
void visitStaticExclusiveOnlyAttr(StaticExclusiveOnlyAttr *attr);
|
void visitStaticExclusiveOnlyAttr(StaticExclusiveOnlyAttr *attr);
|
||||||
void visitManualOwnershipAttr(ManualOwnershipAttr *attr);
|
|
||||||
void visitWeakLinkedAttr(WeakLinkedAttr *attr);
|
void visitWeakLinkedAttr(WeakLinkedAttr *attr);
|
||||||
void visitSILGenNameAttr(SILGenNameAttr *attr);
|
void visitSILGenNameAttr(SILGenNameAttr *attr);
|
||||||
void visitLifetimeAttr(LifetimeAttr *attr);
|
void visitLifetimeAttr(LifetimeAttr *attr);
|
||||||
@@ -8408,13 +8408,6 @@ void AttributeChecker::visitStaticExclusiveOnlyAttr(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttributeChecker::visitManualOwnershipAttr(ManualOwnershipAttr *attr) {
|
|
||||||
if (Ctx.LangOpts.hasFeature(Feature::ManualOwnership))
|
|
||||||
return;
|
|
||||||
|
|
||||||
diagnoseAndRemoveAttr(attr, diag::attr_manual_ownership_experimental);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AttributeChecker::visitWeakLinkedAttr(WeakLinkedAttr *attr) {
|
void AttributeChecker::visitWeakLinkedAttr(WeakLinkedAttr *attr) {
|
||||||
if (!Ctx.LangOpts.Target.isOSBinFormatCOFF())
|
if (!Ctx.LangOpts.Target.isOSBinFormatCOFF())
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1620,8 +1620,8 @@ namespace {
|
|||||||
UNINTERESTING_ATTR(NoAllocation)
|
UNINTERESTING_ATTR(NoAllocation)
|
||||||
UNINTERESTING_ATTR(NoRuntime)
|
UNINTERESTING_ATTR(NoRuntime)
|
||||||
UNINTERESTING_ATTR(NoExistentials)
|
UNINTERESTING_ATTR(NoExistentials)
|
||||||
|
UNINTERESTING_ATTR(NoManualOwnership)
|
||||||
UNINTERESTING_ATTR(NoObjCBridging)
|
UNINTERESTING_ATTR(NoObjCBridging)
|
||||||
UNINTERESTING_ATTR(ManualOwnership)
|
|
||||||
UNINTERESTING_ATTR(Inlinable)
|
UNINTERESTING_ATTR(Inlinable)
|
||||||
UNINTERESTING_ATTR(Effects)
|
UNINTERESTING_ATTR(Effects)
|
||||||
UNINTERESTING_ATTR(Expose)
|
UNINTERESTING_ATTR(Expose)
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ public struct Pair {
|
|||||||
var x: Int
|
var x: Int
|
||||||
var y: Int
|
var y: Int
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
consuming func midpoint(_ other: borrowing Pair) -> Pair {
|
consuming func midpoint(_ other: borrowing Pair) -> Pair {
|
||||||
return Pair(x: (x + other.x) / 2, y: (y + other.y) / 2)
|
return Pair(x: (x + other.x) / 2, y: (y + other.y) / 2)
|
||||||
}
|
}
|
||||||
@@ -27,10 +26,8 @@ public class Triangle {
|
|||||||
|
|
||||||
var nontrivial = Whatever()
|
var nontrivial = Whatever()
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
consuming func consuming() {}
|
consuming func consuming() {}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
borrowing func borrowing() {}
|
borrowing func borrowing() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,51 +41,41 @@ func borrow_generic<T>(_ t: borrowing T) {}
|
|||||||
|
|
||||||
/// MARK: return statements
|
/// MARK: return statements
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
public func basic_return1() -> Triangle {
|
public func basic_return1() -> Triangle {
|
||||||
let x = Triangle()
|
let x = Triangle()
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
public func basic_return2(t: Triangle) -> Triangle {
|
public func basic_return2(t: Triangle) -> Triangle {
|
||||||
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
|
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
public func basic_return2_fixed(t: Triangle) -> Triangle {
|
public func basic_return2_fixed(t: Triangle) -> Triangle {
|
||||||
return copy t
|
return copy t
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
public func basic_return3() -> Triangle {
|
public func basic_return3() -> Triangle {
|
||||||
return Triangle()
|
return Triangle()
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func return_borrowed(_ t: borrowing Triangle) -> Triangle {
|
func return_borrowed(_ t: borrowing Triangle) -> Triangle {
|
||||||
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
|
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func return_borrowed_fixed(_ t: borrowing Triangle) -> Triangle {
|
func return_borrowed_fixed(_ t: borrowing Triangle) -> Triangle {
|
||||||
return copy t
|
return copy t
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: there's no workaround to this; it acts like a var so it's the same class of problem (rdar://161359163)
|
// FIXME: there's no workaround to this; it acts like a var so it's the same class of problem (rdar://161359163)
|
||||||
@_manualOwnership
|
|
||||||
func return_consumingParam(_ t: consuming Triangle) -> Triangle {
|
func return_consumingParam(_ t: consuming Triangle) -> Triangle {
|
||||||
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
|
return t // expected-warning {{independent copy of 't' is required here; write 'copy' to acknowledge or 'consume' to elide}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func return_consumingParam_no_workaround(_ t: consuming Triangle) -> Triangle {
|
func return_consumingParam_no_workaround(_ t: consuming Triangle) -> Triangle {
|
||||||
return copy t
|
return copy t
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func return_owned(_ t: __owned Triangle) -> Triangle {
|
func return_owned(_ t: __owned Triangle) -> Triangle {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func reassign_with_lets() -> Triangle {
|
func reassign_with_lets() -> Triangle {
|
||||||
let x = Triangle()
|
let x = Triangle()
|
||||||
let y = x
|
let y = x
|
||||||
@@ -96,7 +83,6 @@ func reassign_with_lets() -> Triangle {
|
|||||||
return z
|
return z
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func renamed_return(_ cond: Bool, _ a: Triangle) -> Triangle {
|
func renamed_return(_ cond: Bool, _ a: Triangle) -> Triangle {
|
||||||
let b = a
|
let b = a
|
||||||
let c = b
|
let c = b
|
||||||
@@ -105,7 +91,6 @@ func renamed_return(_ cond: Bool, _ a: Triangle) -> Triangle {
|
|||||||
return c // expected-warning {{independent copy of 'c' is required}}
|
return c // expected-warning {{independent copy of 'c' is required}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func renamed_return_fix1(_ cond: Bool, _ a: Triangle) -> Triangle {
|
func renamed_return_fix1(_ cond: Bool, _ a: Triangle) -> Triangle {
|
||||||
let b = copy a
|
let b = copy a
|
||||||
let c = copy b // FIXME: not needed! Is explicit_copy_value is blocking propagation? (rdar://161359163)
|
let c = copy b // FIXME: not needed! Is explicit_copy_value is blocking propagation? (rdar://161359163)
|
||||||
@@ -114,8 +99,7 @@ func renamed_return_fix1(_ cond: Bool, _ a: Triangle) -> Triangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: this crashes CopyPropagation! (rdar://161360764)
|
// FIXME: this crashes CopyPropagation! (rdar://161360764)
|
||||||
//@_manualOwnership
|
////func renamed_return_fix2(_ cond: Bool, _ a: Triangle) -> Triangle {
|
||||||
//func renamed_return_fix2(_ cond: Bool, _ a: Triangle) -> Triangle {
|
|
||||||
// let b = a
|
// let b = a
|
||||||
// let c = b
|
// let c = b
|
||||||
// if cond { return copy b }
|
// if cond { return copy b }
|
||||||
@@ -124,20 +108,17 @@ func renamed_return_fix1(_ cond: Bool, _ a: Triangle) -> Triangle {
|
|||||||
|
|
||||||
/// MARK: method calls
|
/// MARK: method calls
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func basic_methods_borrowing(_ t1: Triangle) {
|
func basic_methods_borrowing(_ t1: Triangle) {
|
||||||
let t2 = Triangle()
|
let t2 = Triangle()
|
||||||
t1.borrowing()
|
t1.borrowing()
|
||||||
t2.borrowing()
|
t2.borrowing()
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func basic_methods_consuming(_ t1: Triangle) {
|
func basic_methods_consuming(_ t1: Triangle) {
|
||||||
let t2 = Triangle()
|
let t2 = Triangle()
|
||||||
t1.consuming() // expected-warning {{independent copy of 't1' is required}}
|
t1.consuming() // expected-warning {{independent copy of 't1' is required}}
|
||||||
t2.consuming()
|
t2.consuming()
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func basic_methods_consuming_fixed(_ t1: Triangle) {
|
func basic_methods_consuming_fixed(_ t1: Triangle) {
|
||||||
let t2 = Triangle()
|
let t2 = Triangle()
|
||||||
|
|
||||||
@@ -148,19 +129,15 @@ func basic_methods_consuming_fixed(_ t1: Triangle) {
|
|||||||
open class OpenClass {
|
open class OpenClass {
|
||||||
open func classMethod() {}
|
open func classMethod() {}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func callOpenMethod(_ c: OpenClass) {
|
func callOpenMethod(_ c: OpenClass) {
|
||||||
return c.classMethod()
|
return c.classMethod()
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func consumingFunc(_ t0: consuming Triangle) -> Bool { return false }
|
func consumingFunc(_ t0: consuming Triangle) -> Bool { return false }
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func plainFunc(_ t0: Triangle) {}
|
func plainFunc(_ t0: Triangle) {}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func basic_function_call(_ t1: Triangle) {
|
func basic_function_call(_ t1: Triangle) {
|
||||||
consumingFunc(t1) // expected-warning {{independent copy of 't1' is required}}
|
consumingFunc(t1) // expected-warning {{independent copy of 't1' is required}}
|
||||||
consumingFunc(copy t1)
|
consumingFunc(copy t1)
|
||||||
@@ -169,13 +146,11 @@ func basic_function_call(_ t1: Triangle) {
|
|||||||
|
|
||||||
/// MARK: control-flow
|
/// MARK: control-flow
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func check_vars(_ t: Triangle, _ b: Bool) -> Triangle {
|
func check_vars(_ t: Triangle, _ b: Bool) -> Triangle {
|
||||||
var x = Triangle()
|
var x = Triangle()
|
||||||
if b { x = t } // expected-warning {{independent copy of 't' is required}}
|
if b { x = t } // expected-warning {{independent copy of 't' is required}}
|
||||||
return x // expected-warning {{independent copy of 'x' is required}}
|
return x // expected-warning {{independent copy of 'x' is required}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func check_vars_fixed(_ t: Triangle, _ b: Bool) -> Triangle {
|
func check_vars_fixed(_ t: Triangle, _ b: Bool) -> Triangle {
|
||||||
var x = Triangle()
|
var x = Triangle()
|
||||||
if b { x = copy t }
|
if b { x = copy t }
|
||||||
@@ -185,45 +160,38 @@ func check_vars_fixed(_ t: Triangle, _ b: Bool) -> Triangle {
|
|||||||
// FIXME: var's still have some issues
|
// FIXME: var's still have some issues
|
||||||
// (1) MandatoryRedundantLoadElimination introduces a 'copy_value' in place of a 'load [copy]' (rdar://161359163)
|
// (1) MandatoryRedundantLoadElimination introduces a 'copy_value' in place of a 'load [copy]' (rdar://161359163)
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func reassignments_0() -> Triangle {
|
func reassignments_0() -> Triangle {
|
||||||
var t3 = Triangle()
|
var t3 = Triangle()
|
||||||
t3 = Triangle()
|
t3 = Triangle()
|
||||||
return t3 // expected-warning {{independent copy of 't3' is required}}
|
return t3 // expected-warning {{independent copy of 't3' is required}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func reassignments_0_fixed_1() -> Triangle {
|
func reassignments_0_fixed_1() -> Triangle {
|
||||||
var t3 = Triangle()
|
var t3 = Triangle()
|
||||||
t3 = Triangle()
|
t3 = Triangle()
|
||||||
return copy t3
|
return copy t3
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func reassignments_0_fixed_2() -> Triangle {
|
func reassignments_0_fixed_2() -> Triangle {
|
||||||
var t3 = Triangle()
|
var t3 = Triangle()
|
||||||
t3 = Triangle()
|
t3 = Triangle()
|
||||||
return consume t3
|
return consume t3
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func reassignments_1() {
|
func reassignments_1() {
|
||||||
var t3 = Triangle()
|
var t3 = Triangle()
|
||||||
t3 = Triangle()
|
t3 = Triangle()
|
||||||
t3.borrowing() // expected-warning {{accessing 't3' may produce a copy; write 'copy' to acknowledge or 'consume' to elide}}
|
t3.borrowing() // expected-warning {{accessing 't3' may produce a copy; write 'copy' to acknowledge or 'consume' to elide}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func reassignments_1_fixed_1() {
|
func reassignments_1_fixed_1() {
|
||||||
var t3 = Triangle()
|
var t3 = Triangle()
|
||||||
t3 = Triangle()
|
t3 = Triangle()
|
||||||
(copy t3).borrowing()
|
(copy t3).borrowing()
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func reassignments_1_fixed_2() {
|
func reassignments_1_fixed_2() {
|
||||||
var t3 = Triangle()
|
var t3 = Triangle()
|
||||||
t3 = Triangle()
|
t3 = Triangle()
|
||||||
(consume t3).borrowing()
|
(consume t3).borrowing()
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
public func basic_loop_trivial_values(_ t: Triangle, _ xs: [Triangle]) {
|
public func basic_loop_trivial_values(_ t: Triangle, _ xs: [Triangle]) {
|
||||||
var p: Pair = t.a
|
var p: Pair = t.a
|
||||||
for x in xs { // expected-warning {{independent copy of 'xs' is required}}
|
for x in xs { // expected-warning {{independent copy of 'xs' is required}}
|
||||||
@@ -231,7 +199,6 @@ public func basic_loop_trivial_values(_ t: Triangle, _ xs: [Triangle]) {
|
|||||||
}
|
}
|
||||||
t.a = p
|
t.a = p
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
public func basic_loop_trivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
|
public func basic_loop_trivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
|
||||||
var p: Pair = t.a
|
var p: Pair = t.a
|
||||||
for x in copy xs {
|
for x in copy xs {
|
||||||
@@ -246,7 +213,6 @@ public func basic_loop_trivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
|
|||||||
// There's complexity in auto-generating a read accessor for classes, but if it's provided
|
// There's complexity in auto-generating a read accessor for classes, but if it's provided
|
||||||
// we could then allow someone to elide the copy with a `borrow x` expression.
|
// we could then allow someone to elide the copy with a `borrow x` expression.
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
public func basic_loop_nontrivial_values(_ t: Triangle, _ xs: [Triangle]) {
|
public func basic_loop_nontrivial_values(_ t: Triangle, _ xs: [Triangle]) {
|
||||||
var p: Pair = t.nontrivial.a // expected-warning {{accessing 't.nontrivial' may produce a copy}}
|
var p: Pair = t.nontrivial.a // expected-warning {{accessing 't.nontrivial' may produce a copy}}
|
||||||
for x in xs { // expected-warning {{independent copy of 'xs' is required}}
|
for x in xs { // expected-warning {{independent copy of 'xs' is required}}
|
||||||
@@ -255,7 +221,6 @@ public func basic_loop_nontrivial_values(_ t: Triangle, _ xs: [Triangle]) {
|
|||||||
t.nontrivial.a = p // expected-warning {{accessing 't.nontrivial' may produce a copy}}
|
t.nontrivial.a = p // expected-warning {{accessing 't.nontrivial' may produce a copy}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
public func basic_loop_nontrivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
|
public func basic_loop_nontrivial_values_fixed(_ t: Triangle, _ xs: [Triangle]) {
|
||||||
var p: Pair = (copy t.nontrivial).a
|
var p: Pair = (copy t.nontrivial).a
|
||||||
for x in copy xs {
|
for x in copy xs {
|
||||||
@@ -264,7 +229,6 @@ public func basic_loop_nontrivial_values_fixed(_ t: Triangle, _ xs: [Triangle])
|
|||||||
(copy t.nontrivial).a = p
|
(copy t.nontrivial).a = p
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
public func basic_loop_nontrivial_values_reduced_copies(_ t: Triangle, _ xs: [Triangle]) {
|
public func basic_loop_nontrivial_values_reduced_copies(_ t: Triangle, _ xs: [Triangle]) {
|
||||||
// FIXME: confusing variable names are chosen (rdar://161360537)
|
// FIXME: confusing variable names are chosen (rdar://161360537)
|
||||||
let nt = t.nontrivial // expected-warning {{accessing 'nt' may produce a copy}}
|
let nt = t.nontrivial // expected-warning {{accessing 'nt' may produce a copy}}
|
||||||
@@ -275,7 +239,6 @@ public func basic_loop_nontrivial_values_reduced_copies(_ t: Triangle, _ xs: [Tr
|
|||||||
}
|
}
|
||||||
nt.a = p
|
nt.a = p
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
public func basic_loop_nontrivial_values_reduced_copies_fixed(_ t: Triangle, _ xs: [Triangle]) {
|
public func basic_loop_nontrivial_values_reduced_copies_fixed(_ t: Triangle, _ xs: [Triangle]) {
|
||||||
let nt = copy t.nontrivial
|
let nt = copy t.nontrivial
|
||||||
var p: Pair = nt.a
|
var p: Pair = nt.a
|
||||||
@@ -292,24 +255,20 @@ let ref_result = [5, 13, 29]
|
|||||||
|
|
||||||
// FIXME: if we had a borrow operator, we could allow people to elide these simple copies that
|
// FIXME: if we had a borrow operator, we could allow people to elide these simple copies that
|
||||||
// are present to avoid exclusivity issues. We'd need to start generating read coroutines.
|
// are present to avoid exclusivity issues. We'd need to start generating read coroutines.
|
||||||
@_manualOwnership
|
|
||||||
func access_global_1() -> Int {
|
func access_global_1() -> Int {
|
||||||
return ref_result[2] // expected-warning {{accessing 'ref_result' may produce a copy}}
|
return ref_result[2] // expected-warning {{accessing 'ref_result' may produce a copy}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func access_global_1_fixed() -> Int {
|
func access_global_1_fixed() -> Int {
|
||||||
return (copy ref_result)[2]
|
return (copy ref_result)[2]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// MARK: closures
|
/// MARK: closures
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func closure_basic(_ t: Triangle) -> () -> Triangle {
|
func closure_basic(_ t: Triangle) -> () -> Triangle {
|
||||||
return { // expected-warning {{closure capture of 't' requires independent copy of it; write [t = copy t]}}
|
return { // expected-warning {{closure capture of 't' requires independent copy of it; write [t = copy t]}}
|
||||||
return t // expected-warning {{independent copy of 't' is required}}
|
return t // expected-warning {{independent copy of 't' is required}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func closure_basic_almost_fixed_1(_ t: Triangle) -> () -> Triangle {
|
func closure_basic_almost_fixed_1(_ t: Triangle) -> () -> Triangle {
|
||||||
// FIXME: Closure capture lists need to support the short-hand [copy t] that makes the
|
// FIXME: Closure capture lists need to support the short-hand [copy t] that makes the
|
||||||
// closure capture parameter @owned, rather than @guaranteed. Only can work for Copyable types!
|
// closure capture parameter @owned, rather than @guaranteed. Only can work for Copyable types!
|
||||||
@@ -318,21 +277,18 @@ func closure_basic_almost_fixed_1(_ t: Triangle) -> () -> Triangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func closure_basic_almost_fixed_2(_ x: Triangle) -> () -> Triangle {
|
func closure_basic_almost_fixed_2(_ x: Triangle) -> () -> Triangle {
|
||||||
return { // expected-warning {{closure capture of 'x' requires independent copy of it; write [x = copy x]}}
|
return { // expected-warning {{closure capture of 'x' requires independent copy of it; write [x = copy x]}}
|
||||||
return copy x
|
return copy x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func closure_basic_fixed(_ t: Triangle) -> () -> Triangle {
|
func closure_basic_fixed(_ t: Triangle) -> () -> Triangle {
|
||||||
return { [x = copy t] in
|
return { [x = copy t] in
|
||||||
return copy x
|
return copy x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func closure_copies_in_body(_ t: Triangle) -> () -> Triangle {
|
func closure_copies_in_body(_ t: Triangle) -> () -> Triangle {
|
||||||
return { [x = copy t] in
|
return { [x = copy t] in
|
||||||
eat(x) // expected-warning {{independent copy of 'x' is required}}
|
eat(x) // expected-warning {{independent copy of 'x' is required}}
|
||||||
@@ -342,7 +298,6 @@ func closure_copies_in_body(_ t: Triangle) -> () -> Triangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func closure_copies_in_body_noescape(_ t: Triangle) -> Triangle {
|
func closure_copies_in_body_noescape(_ t: Triangle) -> Triangle {
|
||||||
let f = { [x = copy t] in
|
let f = { [x = copy t] in
|
||||||
eat(x) // expected-warning {{independent copy of 'x' is required}}
|
eat(x) // expected-warning {{independent copy of 'x' is required}}
|
||||||
@@ -353,25 +308,20 @@ func closure_copies_in_body_noescape(_ t: Triangle) -> Triangle {
|
|||||||
return f()
|
return f()
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func simple_assert(_ f: @autoclosure () -> Bool) {
|
func simple_assert(_ f: @autoclosure () -> Bool) {
|
||||||
guard f() else { fatalError() }
|
guard f() else { fatalError() }
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func try_to_assert(_ n: Int, _ names: [String]) {
|
func try_to_assert(_ n: Int, _ names: [String]) {
|
||||||
simple_assert(names.count == n)
|
simple_assert(names.count == n)
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func copy_in_autoclosure(_ t: Triangle) {
|
func copy_in_autoclosure(_ t: Triangle) {
|
||||||
simple_assert(consumingFunc(t)) // expected-warning {{independent copy of 't' is required}}
|
simple_assert(consumingFunc(t)) // expected-warning {{independent copy of 't' is required}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func copy_in_autoclosure_fixed(_ t: Triangle) {
|
func copy_in_autoclosure_fixed(_ t: Triangle) {
|
||||||
simple_assert(consumingFunc(copy t))
|
simple_assert(consumingFunc(copy t))
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func nested_closures(_ t: Triangle) -> () -> (() -> Triangle) {
|
func nested_closures(_ t: Triangle) -> () -> (() -> Triangle) {
|
||||||
return { // expected-warning {{closure capture of 't' requires independent copy of it; write [t = copy t]}}
|
return { // expected-warning {{closure capture of 't' requires independent copy of it; write [t = copy t]}}
|
||||||
{ eat(t) }() // expected-warning {{independent copy of 't' is required}}
|
{ eat(t) }() // expected-warning {{independent copy of 't' is required}}
|
||||||
@@ -381,7 +331,6 @@ func nested_closures(_ t: Triangle) -> () -> (() -> Triangle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func nested_closures_fixed(_ t: Triangle) -> () -> (() -> Triangle) {
|
func nested_closures_fixed(_ t: Triangle) -> () -> (() -> Triangle) {
|
||||||
return { [a = copy t] in
|
return { [a = copy t] in
|
||||||
{ eat(copy a) }()
|
{ eat(copy a) }()
|
||||||
@@ -391,19 +340,26 @@ func nested_closures_fixed(_ t: Triangle) -> () -> (() -> Triangle) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@_noManualOwnership
|
||||||
|
func nested_closures_DISABLED(_ t: Triangle) -> () -> (() -> Triangle) {
|
||||||
|
return {
|
||||||
|
{ eat(t) }()
|
||||||
|
return {
|
||||||
|
simple_assert(consumingFunc(t))
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// MARK: generics
|
/// MARK: generics
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func return_generic<T>(_ t: T) -> T {
|
func return_generic<T>(_ t: T) -> T {
|
||||||
return t // expected-warning {{accessing 't' may produce a copy}}
|
return t // expected-warning {{accessing 't' may produce a copy}}
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func return_generic_fixed<T>(_ t: T) -> T {
|
func return_generic_fixed<T>(_ t: T) -> T {
|
||||||
return copy t
|
return copy t
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func reassign_with_lets<T>(_ t: T) -> T {
|
func reassign_with_lets<T>(_ t: T) -> T {
|
||||||
let x = t // expected-warning {{accessing 't' may produce a copy}}
|
let x = t // expected-warning {{accessing 't' may produce a copy}}
|
||||||
let y = x // expected-warning {{accessing 'x' may produce a copy}}
|
let y = x // expected-warning {{accessing 'x' may produce a copy}}
|
||||||
@@ -412,7 +368,6 @@ func reassign_with_lets<T>(_ t: T) -> T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: copy propagation has no effect on address-only types, so this is quite verbose.
|
// FIXME: copy propagation has no effect on address-only types, so this is quite verbose.
|
||||||
@_manualOwnership
|
|
||||||
func reassign_with_lets_fixed<T>(_ t: T) -> T {
|
func reassign_with_lets_fixed<T>(_ t: T) -> T {
|
||||||
let x = copy t
|
let x = copy t
|
||||||
let y = copy x
|
let y = copy x
|
||||||
@@ -420,21 +375,25 @@ func reassign_with_lets_fixed<T>(_ t: T) -> T {
|
|||||||
return copy z
|
return copy z
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func copy_generic<T>(_ t: T) {
|
func copy_generic<T>(_ t: T) {
|
||||||
consume_generic(t) // expected-warning {{accessing 't' may produce a copy}}
|
consume_generic(t) // expected-warning {{accessing 't' may produce a copy}}
|
||||||
borrow_generic(t)
|
borrow_generic(t)
|
||||||
consume_generic(t) // expected-warning {{accessing 't' may produce a copy}}
|
consume_generic(t) // expected-warning {{accessing 't' may produce a copy}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
@_noManualOwnership
|
||||||
|
func copy_generic_DISABLED<T>(_ t: T) {
|
||||||
|
consume_generic(t)
|
||||||
|
borrow_generic(t)
|
||||||
|
consume_generic(t)
|
||||||
|
}
|
||||||
|
|
||||||
func copy_generic_fixed<T>(_ t: T) {
|
func copy_generic_fixed<T>(_ t: T) {
|
||||||
consume_generic(copy t)
|
consume_generic(copy t)
|
||||||
borrow_generic(t)
|
borrow_generic(t)
|
||||||
consume_generic(copy t)
|
consume_generic(copy t)
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func benchCaptureProp<S : Sequence>(
|
func benchCaptureProp<S : Sequence>(
|
||||||
_ s: S, _ f: (S.Element, S.Element) -> S.Element) -> S.Element {
|
_ s: S, _ f: (S.Element, S.Element) -> S.Element) -> S.Element {
|
||||||
|
|
||||||
@@ -444,7 +403,6 @@ func benchCaptureProp<S : Sequence>(
|
|||||||
IteratorSequence(it) // expected-warning {{accessing 'it' may produce a copy}}
|
IteratorSequence(it) // expected-warning {{accessing 'it' may produce a copy}}
|
||||||
.reduce(initial, f)
|
.reduce(initial, f)
|
||||||
}
|
}
|
||||||
@_manualOwnership
|
|
||||||
func benchCaptureProp_fixed<S : Sequence>(
|
func benchCaptureProp_fixed<S : Sequence>(
|
||||||
_ s: S, _ f: (S.Element, S.Element) -> S.Element) -> S.Element {
|
_ s: S, _ f: (S.Element, S.Element) -> S.Element) -> S.Element {
|
||||||
|
|
||||||
@@ -456,12 +414,10 @@ func benchCaptureProp_fixed<S : Sequence>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension FixedWidthInteger {
|
extension FixedWidthInteger {
|
||||||
@_manualOwnership
|
|
||||||
func leftRotate(_ distance: Int) -> Self {
|
func leftRotate(_ distance: Int) -> Self {
|
||||||
return (self << distance) | (self >> (Self.bitWidth - distance))
|
return (self << distance) | (self >> (Self.bitWidth - distance))
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
mutating func rotatedLeft(_ distance: Int) {
|
mutating func rotatedLeft(_ distance: Int) {
|
||||||
self = (copy self).leftRotate(distance)
|
self = (copy self).leftRotate(distance)
|
||||||
}
|
}
|
||||||
@@ -470,7 +426,6 @@ extension FixedWidthInteger {
|
|||||||
struct CollectionOf32BitLittleEndianIntegers<BaseCollection: Collection> where BaseCollection.Element == UInt8 {
|
struct CollectionOf32BitLittleEndianIntegers<BaseCollection: Collection> where BaseCollection.Element == UInt8 {
|
||||||
var baseCollection: BaseCollection
|
var baseCollection: BaseCollection
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
init(_ baseCollection: BaseCollection) {
|
init(_ baseCollection: BaseCollection) {
|
||||||
precondition(baseCollection.count % 4 == 0)
|
precondition(baseCollection.count % 4 == 0)
|
||||||
self.baseCollection = baseCollection // expected-warning {{accessing 'baseCollection' may produce a copy}}
|
self.baseCollection = baseCollection // expected-warning {{accessing 'baseCollection' may produce a copy}}
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ public class Donut : Food {
|
|||||||
|
|
||||||
override init() {
|
override init() {
|
||||||
super.init()
|
super.init()
|
||||||
self.calories = 100
|
self.calories = 100 // expected-warning {{exclusive access here will be checked at runtime}}
|
||||||
}
|
}
|
||||||
|
|
||||||
convenience init(calories c: Int) {
|
convenience init(calories c: Int) {
|
||||||
self.init()
|
self.init()
|
||||||
self.calories = c
|
self.calories = c // expected-warning {{exclusive access here will be checked at runtime}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,19 +31,21 @@ extension Int { func greaterThanZero() -> Bool { self > 0 } }
|
|||||||
|
|
||||||
var expectedCalories: Array<Int> = [120, 203, 1502]
|
var expectedCalories: Array<Int> = [120, 203, 1502]
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func accessGlobal_map() -> Array<Donut> {
|
func accessGlobal_map() -> Array<Donut> {
|
||||||
return expectedCalories.map(Donut.init(calories:)) // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
|
return expectedCalories.map(Donut.init(calories:)) // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func accessGlobal_member() -> Int {
|
func accessGlobal_member() -> Int {
|
||||||
return expectedCalories.count // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
|
return expectedCalories.count // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@_noManualOwnership
|
||||||
|
func accessGlobal_member_DISABLED() -> Int {
|
||||||
|
return expectedCalories.count
|
||||||
|
}
|
||||||
|
|
||||||
var globalDonut: Donut = Donut()
|
var globalDonut: Donut = Donut()
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func accessGlobalClass() {
|
func accessGlobalClass() {
|
||||||
let x = globalDonut.calories // expected-warning {{accessing 'globalDonut' here may incur runtime exclusivity check, because it involves a global variable}}
|
let x = globalDonut.calories // expected-warning {{accessing 'globalDonut' here may incur runtime exclusivity check, because it involves a global variable}}
|
||||||
// expected-warning@-1 {{exclusive access here will be checked at runtime}}
|
// expected-warning@-1 {{exclusive access here will be checked at runtime}}
|
||||||
@@ -51,20 +53,17 @@ func accessGlobalClass() {
|
|||||||
expectedCalories.append(x) // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
|
expectedCalories.append(x) // expected-warning {{accessing 'expectedCalories' here may incur runtime exclusivity check, because it involves a global variable}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func accessClassSimple(_ d2: Donut) -> Int {
|
func accessClassSimple(_ d2: Donut) -> Int {
|
||||||
let d1 = Donut()
|
let d1 = Donut()
|
||||||
return d1.calories // expected-warning {{exclusive access here will be checked at runtime}}
|
return d1.calories // expected-warning {{exclusive access here will be checked at runtime}}
|
||||||
+ d2.calories // expected-warning {{exclusive access here will be checked at runtime}}
|
+ d2.calories // expected-warning {{exclusive access here will be checked at runtime}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func accessClassParam_chain(_ donut: Donut) -> Int {
|
func accessClassParam_chain(_ donut: Donut) -> Int {
|
||||||
return donut.next?.next?.calories ?? Int.max
|
return donut.next?.next?.calories ?? Int.max
|
||||||
// expected-warning@-1 {{exclusive access here will be checked at runtime}}
|
// expected-warning@-1 {{exclusive access here will be checked at runtime}}
|
||||||
}
|
}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func accessClassLocal_chain() -> Int {
|
func accessClassLocal_chain() -> Int {
|
||||||
let donut = Donut()
|
let donut = Donut()
|
||||||
return donut.next?.next?.calories ?? Int.max
|
return donut.next?.next?.calories ?? Int.max
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ class TriangleClass {
|
|||||||
// CHECK-NEXT: destroy_value [[SHAPE]]
|
// CHECK-NEXT: destroy_value [[SHAPE]]
|
||||||
// CHECK-NEXT: return [[COPY]]
|
// CHECK-NEXT: return [[COPY]]
|
||||||
// CHECK-NEXT: } // end sil function 'basic_access_of_loadable'
|
// CHECK-NEXT: } // end sil function 'basic_access_of_loadable'
|
||||||
@_manualOwnership
|
|
||||||
@_silgen_name("basic_access_of_loadable")
|
@_silgen_name("basic_access_of_loadable")
|
||||||
func basic_access_of_loadable(_ t: TriangleClass) -> ShapeClass {
|
func basic_access_of_loadable(_ t: TriangleClass) -> ShapeClass {
|
||||||
return copy t.shape
|
return copy t.shape
|
||||||
@@ -41,7 +40,6 @@ func basic_access_of_loadable(_ t: TriangleClass) -> ShapeClass {
|
|||||||
// CHECK-NEXT: end_access [[ADDR2]]
|
// CHECK-NEXT: end_access [[ADDR2]]
|
||||||
// CHECK: return [[X_COPY]]
|
// CHECK: return [[X_COPY]]
|
||||||
// CHECK-NEXT: } // end sil function 'var_assign'
|
// CHECK-NEXT: } // end sil function 'var_assign'
|
||||||
@_manualOwnership
|
|
||||||
@_silgen_name("var_assign")
|
@_silgen_name("var_assign")
|
||||||
func var_assign(_ t: TriangleClass, _ b: Bool) -> TriangleClass {
|
func var_assign(_ t: TriangleClass, _ b: Bool) -> TriangleClass {
|
||||||
var x = TriangleClass()
|
var x = TriangleClass()
|
||||||
@@ -55,7 +53,6 @@ func var_assign(_ t: TriangleClass, _ b: Bool) -> TriangleClass {
|
|||||||
// CHECK-NEXT: [[IMPL_COPY:%.*]] = copy_value %0
|
// CHECK-NEXT: [[IMPL_COPY:%.*]] = copy_value %0
|
||||||
// CHECK-NEXT: return [[IMPL_COPY]]
|
// CHECK-NEXT: return [[IMPL_COPY]]
|
||||||
// CHECK-NEXT: } // end sil function 'return_borrowed'
|
// CHECK-NEXT: } // end sil function 'return_borrowed'
|
||||||
@_manualOwnership
|
|
||||||
@_silgen_name("return_borrowed")
|
@_silgen_name("return_borrowed")
|
||||||
func return_borrowed(_ t: borrowing TriangleClass) -> TriangleClass {
|
func return_borrowed(_ t: borrowing TriangleClass) -> TriangleClass {
|
||||||
return t
|
return t
|
||||||
@@ -74,7 +71,6 @@ func return_borrowed(_ t: borrowing TriangleClass) -> TriangleClass {
|
|||||||
// CHECK-NEXT: destroy_value
|
// CHECK-NEXT: destroy_value
|
||||||
// CHECK-NEXT: return [[IMPL_COPY]]
|
// CHECK-NEXT: return [[IMPL_COPY]]
|
||||||
// CHECK-NEXT: } // end sil function 'return_consumingParam'
|
// CHECK-NEXT: } // end sil function 'return_consumingParam'
|
||||||
@_manualOwnership
|
|
||||||
@_silgen_name("return_consumingParam")
|
@_silgen_name("return_consumingParam")
|
||||||
func return_consumingParam(_ t: consuming TriangleClass) -> TriangleClass {
|
func return_consumingParam(_ t: consuming TriangleClass) -> TriangleClass {
|
||||||
return t
|
return t
|
||||||
@@ -89,7 +85,6 @@ func return_consumingParam(_ t: consuming TriangleClass) -> TriangleClass {
|
|||||||
// CHECK-NEXT: destroy_value %0
|
// CHECK-NEXT: destroy_value %0
|
||||||
// CHECK-NEXT: return [[IMPL_COPY]]
|
// CHECK-NEXT: return [[IMPL_COPY]]
|
||||||
// CHECK-NEXT: } // end sil function 'return_owned'
|
// CHECK-NEXT: } // end sil function 'return_owned'
|
||||||
@_manualOwnership
|
|
||||||
@_silgen_name("return_owned")
|
@_silgen_name("return_owned")
|
||||||
func return_owned(_ t: __owned TriangleClass) -> TriangleClass {
|
func return_owned(_ t: __owned TriangleClass) -> TriangleClass {
|
||||||
return t
|
return t
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
class C {}
|
class C {}
|
||||||
|
|
||||||
@_manualOwnership
|
|
||||||
func hello() -> (C, C) {
|
func hello() -> (C, C) {
|
||||||
@_noImplicitCopy let x = C() // expected-error {{'@_noImplicitCopy' cannot be used with ManualOwnership}}
|
@_noImplicitCopy let x = C() // expected-error {{'@_noImplicitCopy' cannot be used with ManualOwnership}}
|
||||||
return (x, x)
|
return (x, x)
|
||||||
|
|||||||
Reference in New Issue
Block a user