mirror of
https://github.com/apple/swift.git
synced 2026-03-04 18:24:35 +01:00
[opt-remark] Print out the type when we retain/release.
This can be useful if we can't recognize a retain/release and one needs to reason about what is being retained/released.
This commit is contained in:
@@ -70,7 +70,8 @@ Argument::Argument(ArgumentKey key, SILFunction *f) : key(key) {
|
||||
Argument::Argument(StringRef key, SILType ty)
|
||||
: key(ArgumentKeyKind::Default, key) {
|
||||
llvm::raw_string_ostream stream(val);
|
||||
ty.print(stream);
|
||||
PrintOptions subPrinter = PrintOptions::printSIL();
|
||||
ty.getASTType().print(stream, subPrinter);
|
||||
}
|
||||
|
||||
Argument::Argument(StringRef key, CanType ty)
|
||||
|
||||
@@ -249,7 +249,8 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongRetainInst(
|
||||
// Retains begin a lifetime scope so we infer scan forward.
|
||||
auto remark = RemarkMissed("memory", *sri,
|
||||
SourceLocInferenceBehavior::ForwardScanOnly)
|
||||
<< "retain";
|
||||
<< "retain of type '"
|
||||
<< NV("ValueType", sri->getOperand()->getType()) << "'";
|
||||
for (auto arg : inferredArgs) {
|
||||
remark << arg;
|
||||
}
|
||||
@@ -269,7 +270,8 @@ void OptRemarkGeneratorInstructionVisitor::visitStrongReleaseInst(
|
||||
|
||||
auto remark = RemarkMissed("memory", *sri,
|
||||
SourceLocInferenceBehavior::BackwardScanOnly)
|
||||
<< "release";
|
||||
<< "release of type '"
|
||||
<< NV("ValueType", sri->getOperand()->getType()) << "'";
|
||||
for (auto arg : inferredArgs) {
|
||||
remark << arg;
|
||||
}
|
||||
@@ -288,7 +290,8 @@ void OptRemarkGeneratorInstructionVisitor::visitRetainValueInst(
|
||||
// Retains begin a lifetime scope, so we infer scan forwards.
|
||||
auto remark = RemarkMissed("memory", *rvi,
|
||||
SourceLocInferenceBehavior::ForwardScanOnly)
|
||||
<< "retain";
|
||||
<< "retain of type '"
|
||||
<< NV("ValueType", rvi->getOperand()->getType()) << "'";
|
||||
for (auto arg : inferredArgs) {
|
||||
remark << arg;
|
||||
}
|
||||
@@ -308,7 +311,8 @@ void OptRemarkGeneratorInstructionVisitor::visitReleaseValueInst(
|
||||
// Releases end a lifetime scope so we infer scan backward.
|
||||
auto remark = RemarkMissed("memory", *rvi,
|
||||
SourceLocInferenceBehavior::BackwardScanOnly)
|
||||
<< "release";
|
||||
<< "release of type '"
|
||||
<< NV("ValueType", rvi->getOperand()->getType()) << "'";
|
||||
for (auto arg : inferredArgs) {
|
||||
remark << arg;
|
||||
}
|
||||
|
||||
@@ -7,70 +7,78 @@
|
||||
// works without burdening opt-remark-generator-yaml.swift with having to update all
|
||||
// of the yaml test cases everytime new code is added.
|
||||
|
||||
// CHECK: --- !Missed
|
||||
// CHECK-NEXT: Pass: sil-opt-remark-gen
|
||||
// CHECK-NEXT: Name: sil.memory
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: 63, Column: 5 }
|
||||
// CHECK-NEXT: Function: 'getGlobal()'
|
||||
// CHECK-NEXT: Args:
|
||||
// CHECK-NEXT: - String: retain
|
||||
// CHECK-NEXT: - InferredValue: 'of ''global'''
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: 59, Column: 12 }
|
||||
// CHECK-NEXT: ...
|
||||
// CHECK-NEXT: --- !Missed
|
||||
// CHECK-NEXT: Pass: sil-opt-remark-gen
|
||||
// CHECK-NEXT: Name: sil.memory
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: 71, Column: 5 }
|
||||
// CHECK-NEXT: Function: 'useGlobal()'
|
||||
// CHECK-NEXT: Args:
|
||||
// CHECK-NEXT: - String: retain
|
||||
// CHECK-NEXT: - InferredValue: 'of ''x'''
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: 68, Column: 9 }
|
||||
// CHECK-NEXT: ...
|
||||
// CHECK-NEXT: --- !Missed
|
||||
// CHECK-NEXT: Pass: sil-opt-remark-gen
|
||||
// CHECK-NEXT: Name: sil.memory
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: 71, Column: 12 }
|
||||
// CHECK-NEXT: Function: 'useGlobal()'
|
||||
// CHECK-NEXT: Args:
|
||||
// CHECK-NEXT: - String: release
|
||||
|
||||
// CHECK-NEXT: ...
|
||||
// CHECK-NEXT: --- !Missed
|
||||
// CHECK-NEXT: Pass: sil-opt-remark-gen
|
||||
// CHECK-NEXT: Name: sil.memory
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: 71, Column: 12 }
|
||||
// CHECK-NEXT: Function: 'useGlobal()'
|
||||
// CHECK-NEXT: Args:
|
||||
// CHECK-NEXT: - String: release
|
||||
// CHECK-NEXT: - InferredValue: 'of ''x'''
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: 68, Column: 9 }
|
||||
// CHECK-NEXT: ...
|
||||
|
||||
public class Klass {}
|
||||
|
||||
public var global = Klass()
|
||||
|
||||
// CHECK: --- !Missed
|
||||
// CHECK-NEXT: Pass: sil-opt-remark-gen
|
||||
// CHECK-NEXT: Name: sil.memory
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: [[# @LINE + 12]], Column: 5 }
|
||||
// CHECK-NEXT: Function: 'getGlobal()'
|
||||
// CHECK-NEXT: Args:
|
||||
// CHECK-NEXT: - String: 'retain of type '''
|
||||
// CHECK-NEXT: - ValueType: Klass
|
||||
// CHECK-NEXT: - String: ''''
|
||||
// CHECK-NEXT: - InferredValue: 'of ''global'''
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: [[# @LINE - 14]], Column: 12 }
|
||||
// CHECK-NEXT: ...
|
||||
@inline(never)
|
||||
public func getGlobal() -> Klass {
|
||||
return global // expected-remark @:5 {{retain}}
|
||||
// expected-note @-5:12 {{of 'global'}}
|
||||
return global // expected-remark @:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-19:12 {{of 'global'}}
|
||||
}
|
||||
|
||||
// CHECK-NEXT: --- !Missed
|
||||
// CHECK-NEXT: Pass: sil-opt-remark-gen
|
||||
// CHECK-NEXT: Name: sil.memory
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: [[# @LINE + 40]], Column: 5 }
|
||||
// CHECK-NEXT: Function: 'useGlobal()'
|
||||
// CHECK-NEXT: Args:
|
||||
// CHECK-NEXT: - String: 'retain of type '''
|
||||
// CHECK-NEXT: - ValueType: Klass
|
||||
// CHECK-NEXT: - String: ''''
|
||||
// CHECK-NEXT: - InferredValue: 'of ''x'''
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: [[# @LINE + 29]], Column: 9 }
|
||||
// CHECK-NEXT: ...
|
||||
// CHECK-NEXT: --- !Missed
|
||||
// CHECK-NEXT: Pass: sil-opt-remark-gen
|
||||
// CHECK-NEXT: Name: sil.memory
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: [[# @LINE + 26]], Column: 12 }
|
||||
// CHECK-NEXT: Function: 'useGlobal()'
|
||||
// CHECK-NEXT: Args:
|
||||
// CHECK-NEXT: - String: 'release of type '''
|
||||
// CHECK-NEXT: - ValueType: {{'Array<Any>'|__ContiguousArrayStorageBase}}
|
||||
// CHECK-NEXT: - String: ''''
|
||||
// CHECK-NEXT: ...
|
||||
// CHECK-NEXT: --- !Missed
|
||||
// CHECK-NEXT: Pass: sil-opt-remark-gen
|
||||
// CHECK-NEXT: Name: sil.memory
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: [[# @LINE + 15]], Column: 12 }
|
||||
// CHECK-NEXT: Function: 'useGlobal()'
|
||||
// CHECK-NEXT: Args:
|
||||
// CHECK-NEXT: - String: 'release of type '''
|
||||
// CHECK-NEXT: - ValueType: Klass
|
||||
// CHECK-NEXT: - String: ''''
|
||||
// CHECK-NEXT: - InferredValue: 'of ''x'''
|
||||
// CHECK-NEXT: DebugLoc: { File: '{{.*}}opt-remark-generator-yaml.swift',
|
||||
// CHECK-NEXT: Line: [[# @LINE + 4]], Column: 9 }
|
||||
// CHECK-NEXT: ...
|
||||
|
||||
public func useGlobal() {
|
||||
let x = getGlobal()
|
||||
// Make sure that the retain msg is at the beginning of the print and the
|
||||
// releases are the end of the print.
|
||||
print(x) // expected-remark @:5 {{retain}}
|
||||
print(x) // expected-remark @:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-4:9 {{of 'x'}}
|
||||
// expected-remark @-2:12 {{release}}
|
||||
// expected-remark @-3:12 {{release}}
|
||||
// expected-note @-7:9 {{of 'x'}}
|
||||
// We test the type emission above since FileCheck can handle regex.
|
||||
// expected-remark @-3:12 {{release of type}}
|
||||
// expected-remark @-4:12 {{release of type 'Klass'}}
|
||||
// expected-note @-8:9 {{of 'x'}}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ import Builtin
|
||||
|
||||
sil @foo : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
|
||||
bb0(%0 : $Builtin.NativeObject):
|
||||
strong_retain %0 : $Builtin.NativeObject // expected-remark {{retain}}
|
||||
retain_value %0 : $Builtin.NativeObject // expected-remark {{retain}}
|
||||
strong_release %0 : $Builtin.NativeObject // expected-remark {{release}}
|
||||
release_value %0 : $Builtin.NativeObject // expected-remark {{release}}
|
||||
strong_retain %0 : $Builtin.NativeObject // expected-remark {{retain of type 'Builtin.NativeObject'}}
|
||||
retain_value %0 : $Builtin.NativeObject // expected-remark {{retain of type 'Builtin.NativeObject'}}
|
||||
strong_release %0 : $Builtin.NativeObject // expected-remark {{release of type 'Builtin.NativeObject'}}
|
||||
release_value %0 : $Builtin.NativeObject // expected-remark {{release of type 'Builtin.NativeObject'}}
|
||||
%9999 = tuple()
|
||||
return %9999 : $()
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ public var global = Klass()
|
||||
|
||||
@inline(never)
|
||||
public func getGlobal() -> Klass {
|
||||
return global // expected-remark @:5 {{retain}}
|
||||
return global // expected-remark @:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-5:12 {{of 'global'}}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,10 @@ public func useGlobal() {
|
||||
let x = getGlobal()
|
||||
// Make sure that the retain msg is at the beginning of the print and the
|
||||
// releases are the end of the print.
|
||||
print(x) // expected-remark @:5 {{retain}}
|
||||
print(x) // expected-remark @:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-4:9 {{of 'x'}}
|
||||
// expected-remark @-2:12 {{release}}
|
||||
// expected-remark @-3:12 {{release}}
|
||||
// expected-remark @-2:12 {{release of type}}
|
||||
// expected-remark @-3:12 {{release of type 'Klass'}}
|
||||
// expected-note @-7:9 {{of 'x'}}
|
||||
}
|
||||
|
||||
@@ -31,107 +31,107 @@ struct StructWithOwner {
|
||||
// This retain is from the initializers of owner.
|
||||
//
|
||||
// TODO: Should we emit this?
|
||||
var owner = Klass() // expected-remark {{retain}}
|
||||
var owner = Klass() // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-1 {{of 'self.owner'}}
|
||||
// expected-remark @-2 {{release}}
|
||||
// expected-remark @-2 {{release of type 'Klass'}}
|
||||
// expected-note @-3 {{of 'self.owner'}}
|
||||
var state = TrivialState.first
|
||||
}
|
||||
|
||||
func printStructWithOwner(x : StructWithOwner) {
|
||||
print(x) // expected-remark {{retain}}
|
||||
print(x) // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:27 {{of 'x.owner'}}
|
||||
// We should be able to infer the arg here.
|
||||
// expected-remark @-3:12 {{release}}
|
||||
// expected-remark @-3:12 {{release of type}}
|
||||
}
|
||||
|
||||
func printStructWithOwnerOwner(x : StructWithOwner) {
|
||||
print(x.owner) // expected-remark {{retain}}
|
||||
print(x.owner) // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:32 {{of 'x.owner'}}
|
||||
// We should be able to infer the arg here.
|
||||
// expected-remark @-3:18 {{release}}
|
||||
// expected-remark @-3:18 {{release of type}}
|
||||
}
|
||||
|
||||
func returnStructWithOwnerOwner(x: StructWithOwner) -> Klass {
|
||||
return x.owner // expected-remark {{retain}}
|
||||
return x.owner // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:33 {{of 'x.owner'}}
|
||||
}
|
||||
|
||||
func callingAnInitializerStructWithOwner(x: Klass) -> StructWithOwner {
|
||||
return StructWithOwner(owner: x) // expected-remark {{retain}}
|
||||
return StructWithOwner(owner: x) // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:42 {{of 'x'}}
|
||||
}
|
||||
|
||||
struct KlassPair {
|
||||
var lhs: Klass // expected-remark {{retain}}
|
||||
var lhs: Klass // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-1 {{of 'self.lhs'}}
|
||||
// expected-remark @-2 {{release}}
|
||||
// expected-remark @-2 {{release of type 'Klass'}}
|
||||
// expected-note @-3 {{of 'self.lhs'}}
|
||||
var rhs: Klass // expected-remark {{retain}}
|
||||
var rhs: Klass // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-1 {{of 'self.rhs'}}
|
||||
// expected-remark @-2 {{release}}
|
||||
// expected-remark @-2 {{release of type 'Klass'}}
|
||||
// expected-note @-3 {{of 'self.rhs'}}
|
||||
}
|
||||
|
||||
func printKlassPair(x : KlassPair) {
|
||||
// We pattern match columns to ensure we get retain on the p and release on
|
||||
// the end ')'
|
||||
print(x) // expected-remark @:5 {{retain}}
|
||||
print(x) // expected-remark @:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-4:21 {{of 'x.lhs'}}
|
||||
// expected-remark @-2:5 {{retain}}
|
||||
// expected-remark @-2:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-6:21 {{of 'x.rhs'}}
|
||||
// This is a release for Array<Any> for print.
|
||||
// expected-remark @-5:12 {{release}}
|
||||
// expected-remark @-5:12 {{release of type}}
|
||||
}
|
||||
|
||||
func printKlassPairLHS(x : KlassPair) {
|
||||
// We print the remarks at the 'p' and at the ending ')'.
|
||||
print(x.lhs) // expected-remark @:5 {{retain}}
|
||||
print(x.lhs) // expected-remark @:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-3:24 {{of 'x.lhs'}}
|
||||
// Release for Array<Any> needed for print.
|
||||
// expected-remark @-3:16 {{release}}
|
||||
// expected-remark @-3:16 {{release of type}}
|
||||
}
|
||||
|
||||
func returnKlassPairLHS(x: KlassPair) -> Klass {
|
||||
return x.lhs // expected-remark @:14 {{retain}}
|
||||
return x.lhs // expected-remark @:14 {{retain of type 'Klass'}}
|
||||
// expected-note @-2:25 {{of 'x.lhs'}}
|
||||
}
|
||||
|
||||
func callingAnInitializerKlassPair(x: Klass, y: Klass) -> KlassPair {
|
||||
return KlassPair(lhs: x, rhs: y) // expected-remark {{retain}}
|
||||
return KlassPair(lhs: x, rhs: y) // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:36 {{of 'x'}}
|
||||
// expected-remark @-2:5 {{retain}}
|
||||
// expected-remark @-2:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-4:46 {{of 'y'}}
|
||||
}
|
||||
|
||||
func printKlassTuplePair(x : (Klass, Klass)) {
|
||||
// We pattern match columns to ensure we get retain on the p and release on
|
||||
// the end ')'
|
||||
print(x) // expected-remark @:5 {{retain}}
|
||||
print(x) // expected-remark @:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-4:26 {{of 'x'}}
|
||||
// expected-remark @-2:5 {{retain}}
|
||||
// expected-remark @-2:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-6:26 {{of 'x'}}
|
||||
// Release on temp array for print(...).
|
||||
// expected-remark @-5:12 {{release}}
|
||||
// expected-remark @-5:12 {{release of type}}
|
||||
}
|
||||
|
||||
func printKlassTupleLHS(x : (Klass, Klass)) {
|
||||
// We print the remarks at the 'p' and at the ending ')'.
|
||||
print(x.0) // expected-remark @:5 {{retain}}
|
||||
print(x.0) // expected-remark @:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-3:25 {{of 'x'}}
|
||||
// Release on Array<Any> for print.
|
||||
// expected-remark @-3:14 {{release}}
|
||||
// expected-remark @-3:14 {{release of type}}
|
||||
}
|
||||
|
||||
func returnKlassTupleLHS(x: (Klass, Klass)) -> Klass {
|
||||
return x.0 // expected-remark @:12 {{retain}}
|
||||
return x.0 // expected-remark @:12 {{retain of type 'Klass'}}
|
||||
// expected-note @-2:26 {{of 'x'}}
|
||||
}
|
||||
|
||||
func callingAnInitializerKlassTuplePair(x: Klass, y: Klass) -> (Klass, Klass) {
|
||||
return (x, y) // expected-remark {{retain}}
|
||||
return (x, y) // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:41 {{of 'x'}}
|
||||
// expected-remark @-2:5 {{retain}}
|
||||
// expected-remark @-2:5 {{retain of type 'Klass'}}
|
||||
// expected-note @-4:51 {{of 'y'}}
|
||||
}
|
||||
|
||||
@@ -141,22 +141,22 @@ public class SubKlass : Klass {
|
||||
}
|
||||
|
||||
func lookThroughCast(x: SubKlass) -> Klass {
|
||||
return x as Klass // expected-remark {{retain}}
|
||||
return x as Klass // expected-remark {{retain of type 'SubKlass'}}
|
||||
// expected-note @-2:22 {{of 'x'}}
|
||||
}
|
||||
|
||||
func lookThroughRefCast(x: Klass) -> SubKlass {
|
||||
return x as! SubKlass // expected-remark {{retain}}
|
||||
return x as! SubKlass // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:25 {{of 'x'}}
|
||||
}
|
||||
|
||||
func lookThroughEnum(x: Klass?) -> Klass {
|
||||
return x! // expected-remark {{retain}}
|
||||
return x! // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:22 {{of 'x.some'}}
|
||||
}
|
||||
|
||||
func castAsQuestion(x: Klass) -> SubKlass? {
|
||||
x as? SubKlass // expected-remark {{retain}}
|
||||
x as? SubKlass // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2:21 {{of 'x'}}
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ func castAsQuestionDiamond(x: Klass) -> SubKlass? {
|
||||
}
|
||||
|
||||
y.doSomething()
|
||||
return y // expected-remark {{retain}}
|
||||
return y // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-7:28 {{of 'x'}}
|
||||
}
|
||||
|
||||
@@ -177,66 +177,66 @@ func castAsQuestionDiamondGEP(x: KlassPair) -> SubKlass? {
|
||||
|
||||
y.doSomething()
|
||||
// We eliminate the rhs retain/release.
|
||||
return y // expected-remark {{retain}}
|
||||
return y // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-8:31 {{of 'x.lhs'}}
|
||||
}
|
||||
|
||||
// We don't handle this test case as well.
|
||||
func castAsQuestionDiamondGEP2(x: KlassPair) {
|
||||
switch (x.lhs as? SubKlass, x.rhs as? SubKlass) { // expected-remark @:19 {{retain}}
|
||||
switch (x.lhs as? SubKlass, x.rhs as? SubKlass) { // expected-remark @:19 {{retain of type 'Klass'}}
|
||||
// expected-note @-2 {{of 'x.lhs'}}
|
||||
// expected-remark @-2:39 {{retain}}
|
||||
// expected-remark @-2:39 {{retain of type 'Klass'}}
|
||||
// expected-note @-4 {{of 'x.rhs'}}
|
||||
case let (.some(x1), .some(x2)):
|
||||
print(x1, x2) // expected-remark {{retain}}
|
||||
// expected-remark @-1 {{retain}}
|
||||
// expected-remark @-2 {{release}}
|
||||
// expected-remark @-3 {{release}}
|
||||
// expected-remark @-4 {{release}}
|
||||
print(x1, x2) // expected-remark {{retain of type 'Optional<SubKlass>'}}
|
||||
// expected-remark @-1 {{retain of type 'Optional<SubKlass>'}}
|
||||
// expected-remark @-2 {{release of type}}
|
||||
// expected-remark @-3 {{release of type 'Optional<SubKlass>'}}
|
||||
// expected-remark @-4 {{release of type 'Optional<SubKlass>'}}
|
||||
case let (.some(x1), nil):
|
||||
print(x1) // expected-remark {{retain}}
|
||||
// expected-remark @-1 {{release}}
|
||||
// expected-remark @-2 {{release}}
|
||||
print(x1) // expected-remark {{retain of type 'SubKlass'}}
|
||||
// expected-remark @-1 {{release of type}}
|
||||
// expected-remark @-2 {{release of type 'Optional<SubKlass>'}}
|
||||
case let (nil, .some(x2)):
|
||||
print(x2) // expected-remark {{retain}}
|
||||
// expected-remark @-1 {{release}}
|
||||
// expected-remark @-2 {{release}}
|
||||
print(x2) // expected-remark {{retain of type 'SubKlass'}}
|
||||
// expected-remark @-1 {{release of type}}
|
||||
// expected-remark @-2 {{release of type 'Optional<SubKlass>'}}
|
||||
case (nil, nil):
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func inoutKlassPairArgument(x: inout KlassPair) -> Klass {
|
||||
return x.lhs // expected-remark {{retain}}
|
||||
return x.lhs // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2 {{of 'x.lhs'}}
|
||||
}
|
||||
|
||||
func inoutKlassTuplePairArgument(x: inout (Klass, Klass)) -> Klass {
|
||||
return x.0 // expected-remark {{retain}}
|
||||
return x.0 // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2 {{of 'x.0'}}
|
||||
}
|
||||
|
||||
func inoutKlassOptionalArgument(x: inout Klass?) -> Klass {
|
||||
return x! // expected-remark {{retain}}
|
||||
return x! // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2 {{of 'x.some'}}
|
||||
}
|
||||
|
||||
func inoutKlassBangCastArgument(x: inout Klass) -> SubKlass {
|
||||
return x as! SubKlass // expected-remark {{retain}}
|
||||
return x as! SubKlass // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2 {{of 'x'}}
|
||||
}
|
||||
|
||||
func inoutKlassQuestionCastArgument(x: inout Klass) -> SubKlass? {
|
||||
return x as? SubKlass // expected-remark {{retain}}
|
||||
return x as? SubKlass // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2 {{of 'x'}}
|
||||
}
|
||||
|
||||
func inoutKlassBangCastArgument2(x: inout Klass?) -> SubKlass {
|
||||
return x as! SubKlass // expected-remark {{retain}}
|
||||
return x as! SubKlass // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2 {{of 'x.some'}}
|
||||
}
|
||||
|
||||
func inoutKlassQuestionCastArgument2(x: inout Klass?) -> SubKlass? {
|
||||
return x as? SubKlass // expected-remark {{retain}}
|
||||
return x as? SubKlass // expected-remark {{retain of type 'Klass'}}
|
||||
// expected-note @-2 {{of 'x.some'}}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user