Swift: Test for MAD tuple content flow.

This commit is contained in:
Geoffrey White
2023-08-09 14:41:32 +01:00
parent a1234d4235
commit b4b2338144
4 changed files with 1135 additions and 1069 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,8 @@ private class TestSummaries extends SummaryModelCsv {
[
// model to allow data flow through `signum()` as though it were an identity function, for the benefit of testing flow through optional chaining (`x?.`).
";Int;true;signum();;;Argument[-1];ReturnValue;value",
// test Tuple content in MAD
";;false;tupleShiftLeft2(_:);;;Argument[0].TupleElement[1];ReturnValue.TupleElement[0];value",
// test Enum content in MAD
";;false;mkMyEnum2(_:);;;Argument[0];ReturnValue.EnumElement[mySingle:0];value",
";;false;mkOptional2(_:);;;Argument[0];ReturnValue.OptionalSome;value"

View File

@@ -365,6 +365,25 @@ func testTuples2() {
sink(arg: c)
}
func tupleShiftLeft1(_ t: (Int, Int)) -> (Int, Int) {
return (t.1, 0)
}
func tupleShiftLeft2(_ t: (Int, Int)) -> (Int, Int) { return (0, 0) } // modelled flow
func testTuples3() {
let t1 = (1, source())
let t2 = tupleShiftLeft1(t1)
let t3 = tupleShiftLeft2(t1)
sink(arg: t1.0)
sink(arg: t1.1) // $ flow=375
sink(arg: t2.0) // $ flow=375
sink(arg: t2.1)
sink(arg: t3.0) // $ MISSING: flow=375
sink(arg: t3.1)
}
indirect enum MyEnum {
case myNone
case mySingle(Int)
@@ -406,7 +425,7 @@ func testEnums() {
case .myNone:
()
case .mySingle(let a):
sink(arg: a) // $ flow=403
sink(arg: a) // $ flow=422
case .myPair(let a, let b):
sink(arg: a)
sink(arg: b)
@@ -415,7 +434,7 @@ func testEnums() {
}
if case .mySingle(let x) = a {
sink(arg: x) // $ flow=403
sink(arg: x) // $ flow=422
}
if case .myPair(let x, let y) = a {
sink(arg: x)
@@ -431,7 +450,7 @@ func testEnums() {
sink(arg: a)
case .myPair(let a, let b):
sink(arg: a)
sink(arg: b) // $ flow=425
sink(arg: b) // $ flow=444
case let .myCons(a, _):
sink(arg: a)
}
@@ -441,7 +460,7 @@ func testEnums() {
}
if case .myPair(let x, let y) = a {
sink(arg: x)
sink(arg: y) // $ flow=425
sink(arg: y) // $ flow=444
}
let b: MyEnum = .myCons(42, a)
@@ -457,7 +476,7 @@ func testEnums() {
case let .myCons(a, .myPair(b, c)):
sink(arg: a)
sink(arg: b)
sink(arg: c) // $ flow=425
sink(arg: c) // $ flow=444
case let .myCons(a, _):
sink(arg: a)
}
@@ -466,20 +485,20 @@ func testEnums() {
sink(arg: x)
}
if case MyEnum.myPair(let x, let y) = .myPair(source(), 0) {
sink(arg: x) // $ flow=468
sink(arg: x) // $ flow=487
sink(arg: y)
}
if case let .myCons(_, .myPair(_, c)) = b {
sink(arg: c) // $ flow=425
sink(arg: c) // $ flow=444
}
switch (a, b) {
case let (.myPair(a, b), .myCons(c, .myPair(d, e))):
sink(arg: a)
sink(arg: b) // $ flow=425
sink(arg: b) // $ flow=444
sink(arg: c)
sink(arg: d)
sink(arg: e) // $ flow=425
sink(arg: e) // $ flow=444
default:
()
}
@@ -491,11 +510,11 @@ func testEnums() {
let c5 = mkMyEnum2(0)
let c6 = mkMyEnum2(source())
if case MyEnum.mySingle(let d1) = c1 { sink(arg: d1) }
if case MyEnum.mySingle(let d2) = c2 { sink(arg: d2) } // $ flow=488
if case MyEnum.mySingle(let d2) = c2 { sink(arg: d2) } // $ flow=507
if case MyEnum.mySingle(let d3) = c3 { sink(arg: d3) }
if case MyEnum.mySingle(let d4) = c4 { sink(arg: d4) } // $ flow=490
if case MyEnum.mySingle(let d4) = c4 { sink(arg: d4) } // $ flow=509
if case MyEnum.mySingle(let d5) = c5 { sink(arg: d5) }
if case MyEnum.mySingle(let d6) = c6 { sink(arg: d6) } // $ flow=492
if case MyEnum.mySingle(let d6) = c6 { sink(arg: d6) } // $ flow=511
let e1 = Optional.some(0)
let e2 = Optional.some(source())
@@ -504,11 +523,11 @@ func testEnums() {
let e5 = mkOptional2(0)
let e6 = mkOptional2(source())
sink(arg: e1!)
sink(arg: e2!) // $ flow=501
sink(arg: e2!) // $ flow=520
sink(arg: e3!)
sink(arg: e4!) // $ flow=503
sink(arg: e4!) // $ flow=522
sink(arg: e5!)
sink(arg: e6!) // $ flow=505
sink(arg: e6!) // $ flow=524
}
func source2() -> (Int, Int)? { return nil }
@@ -554,8 +573,8 @@ func testOptionalPropertyAccess(y: Int?) {
}
func testIdentityArithmetic() {
sink(arg: +source()) // $ flow=557
sink(arg: (source())) // $ flow=558
sink(arg: +source()) // $ flow=576
sink(arg: (source())) // $ flow=577
}
func sink(str: String) {}
@@ -572,13 +591,13 @@ class MyClass {
extension MyClass {
convenience init(contentsOfFile: String) {
self.init(s: source3())
sink(str: str) // $ flow=574
sink(str: str) // $ flow=593
}
}
func extensionInits(path: String) {
sink(str: MyClass(s: source3()).str) // $ flow=580
sink(str: MyClass(contentsOfFile: path).str) // $ flow=574
sink(str: MyClass(s: source3()).str) // $ flow=599
sink(str: MyClass(contentsOfFile: path).str) // $ flow=593
}
class InoutConstructorClass {
@@ -603,10 +622,10 @@ struct S {
func testKeyPath() {
let s = S(x: source())
let f = \S.x
sink(arg: s[keyPath: f]) // $ flow=604
sink(arg: s[keyPath: f]) // $ flow=623
let inferred : KeyPath<S, Int> = \.x
sink(arg: s[keyPath: inferred]) // $ flow=604
sink(arg: s[keyPath: inferred]) // $ flow=623
}
struct S2 {
@@ -621,13 +640,13 @@ func testNestedKeyPath() {
let s = S(x: source())
let s2 = S2(s: s)
let f = \S2.s.x
sink(arg: s2[keyPath: f]) // $ flow=621
sink(arg: s2[keyPath: f]) // $ flow=640
}
func testArrayKeyPath() {
let array = [source()]
let f = \[Int].[0]
sink(arg: array[keyPath: f]) // $ flow=628
sink(arg: array[keyPath: f]) // $ flow=647
}
struct S2_Optional {
@@ -642,7 +661,7 @@ func testOptionalKeyPath() {
let s = S(x: source())
let s2 = S2_Optional(s: s)
let f = \S2_Optional.s?.x
sink(opt: s2[keyPath: f]) // $ MISSING: flow=642
sink(opt: s2[keyPath: f]) // $ MISSING: flow=661
}
func testSwap() {
@@ -654,57 +673,57 @@ func testSwap() {
x = y
y = t
sink(arg: x)
sink(arg: y) // $ flow=649
sink(arg: y) // $ flow=668
x = source()
y = 0
swap(&x, &y)
sink(arg: x) // $ SPURIOUS: flow=659
sink(arg: y) // $ flow=659
sink(arg: x) // $ SPURIOUS: flow=678
sink(arg: y) // $ flow=678
}
func testArray() {
var arr1 = [1,2,3]
sink(arg: arr1[0])
arr1[1] = source()
sink(arg: arr1[0]) // $ flow=669
sink(arg: arr1[0]) // $ flow=688
sink(arg: arr1)
var arr2 = [source()]
sink(arg: arr2[0]) // $ flow=673
sink(arg: arr2[0]) // $ flow=692
var matrix = [[source()]]
sink(arg: matrix[0])
sink(arg: matrix[0][0]) // $ flow=676
sink(arg: matrix[0][0]) // $ flow=695
var matrix2 = [[1]]
matrix2[0][0] = source()
sink(arg: matrix2[0][0]) // $ flow=681
sink(arg: matrix2[0][0]) // $ flow=700
var arr3 = [1]
var arr4 = arr2 + arr3
sink(arg: arr3[0])
sink(arg: arr4[0]) // $ MISSING: flow=673
sink(arg: arr4[0]) // $ MISSING: flow=692
var arr5 = Array(repeating: source(), count: 2)
sink(arg: arr5[0]) // $ MISSING: flow=689
sink(arg: arr5[0]) // $ MISSING: flow=708
var arr6 = [1,2,3]
arr6.insert(source(), at: 2)
sink(arg: arr6[0]) // $ flow=693
sink(arg: arr6[0]) // $ flow=712
var arr7 = [source()]
sink(arg: arr7.randomElement()!) // $ flow=696
sink(arg: arr7.randomElement()!) // $ flow=715
}
func testSetCollections() {
var set1: Set = [1,2,3]
sink(arg: set1.randomElement()!)
set1.insert(source())
sink(arg: set1.randomElement()!) // $flow=703
sink(arg: set1.randomElement()!) // $ flow=722
let set2 = Set([source()])
sink(arg: set2.randomElement()!) // $ flow=706
sink(arg: set2.randomElement()!) // $ flow=725
}
struct MyOptionals {
@@ -730,13 +749,13 @@ func testWriteOptional() {
mo2!.v2 = source()
mo2!.v3 = source()
sink(arg: v1!) // $ flow=723
sink(arg: v2!) // $ flow=724
sink(arg: v3) // $ flow=725
sink(arg: mo1.v1!) // $ MISSING:flow=726
sink(arg: mo1.v2!) // $ flow=727
sink(arg: mo1.v3) // $ flow=728
sink(arg: mo2!.v1!) // $ MISSING:flow=729
sink(arg: mo2!.v2!) // $ MISSING:flow=730
sink(arg: mo2!.v3) // $ MISSING:flow=731
sink(arg: v1!) // $ flow=742
sink(arg: v2!) // $ flow=743
sink(arg: v3) // $ flow=744
sink(arg: mo1.v1!) // $ MISSING:flow=745
sink(arg: mo1.v2!) // $ flow=746
sink(arg: mo1.v3) // $ flow=747
sink(arg: mo2!.v1!) // $ MISSING:flow=748
sink(arg: mo2!.v2!) // $ MISSING:flow=749
sink(arg: mo2!.v3) // $ MISSING:flow=750
}