mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Fix counters for regions following `else if`s, fix the counters for `else if` conditions, and fix handling of `break` statements. Also while here, clean up the handling of branch exit regions such that we don't generate multiple overlapping regions for each branch, but a single region at the end of the entire `if` statement that accounts for all exiting control flow. rdar://104078910 rdar://104079242
232 lines
11 KiB
Swift
232 lines
11 KiB
Swift
// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -profile-generate -profile-coverage-mapping -emit-sorted-sil -emit-sil -module-name coverage_if %s | %FileCheck %s
|
||
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -emit-ir %s
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo
|
||
func foo(x : Bool) { // CHECK: [[@LINE]]:20 -> {{[0-9]+}}:2 : 0
|
||
// CHECK: [[@LINE+1]]:6 -> [[@LINE+1]]:9 : 0
|
||
if (x) { // CHECK: [[@LINE]]:10 -> [[@LINE+1]]:4 : 1
|
||
}
|
||
|
||
if (!x) { // CHECK: [[@LINE]]:11 -> [[@LINE+2]]:4 : 2
|
||
// ...
|
||
}
|
||
|
||
if (x) { } // CHECK: [[@LINE]]:10 -> [[@LINE]]:13 : 3
|
||
else { } // CHECK: [[@LINE]]:10 -> [[@LINE]]:13 : (0 - 3)
|
||
}
|
||
|
||
foo(x: true);
|
||
foo(x: false);
|
||
|
||
// rdar://29390569 – Make sure we don't add a spurious unreachable empty region.
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo1
|
||
func foo1() -> Int { // CHECK-NEXT: [[@LINE]]:20 -> {{[0-9]+}}:2 : 0
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE]]:15 : 0
|
||
return 0 // CHECK-NEXT: [[@LINE-1]]:16 -> [[@LINE+1]]:4 : 1
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : (0 - 1)
|
||
return 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 2
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : ((0 - 1) - 2)
|
||
return 2
|
||
} // CHECK-NEXT: }
|
||
}
|
||
|
||
// ...but we will add an unreachable region if you write code there.
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo2
|
||
func foo2() -> Int {
|
||
if .random() {
|
||
return 0
|
||
} else if .random() {
|
||
return 1
|
||
} else {
|
||
return 2
|
||
}
|
||
_ = foo1() // CHECK: [[@LINE]]:3 -> [[@LINE+1]]:2 : zero
|
||
}
|
||
|
||
// Make sure we don't add unreachable regions for a labeled jump either.
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo3
|
||
func foo3() -> Int { // CHECK-NEXT: [[@LINE]]:20 -> {{[0-9]+}}:2 : 0
|
||
x: do { // CHECK-NEXT: [[@LINE]]:9 -> [[@LINE+6]]:4 : 0
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE]]:17 : 0
|
||
return 0 // CHECK-NEXT: [[@LINE-1]]:18 -> [[@LINE+1]]:6 : 1
|
||
} else { // CHECK-NEXT: [[@LINE]]:12 -> [[@LINE+2]]:6 : (0 - 1)
|
||
break x
|
||
}
|
||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : (0 - 1)
|
||
return 2
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo4
|
||
func foo4() -> Int {
|
||
x: do {
|
||
if .random() {
|
||
return 0
|
||
} else {
|
||
break x
|
||
}
|
||
let y = 0 // CHECK: [[@LINE]]:13 -> [[@LINE+1]]:4 : zero
|
||
}
|
||
return 2
|
||
}
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo5
|
||
func foo5() throws -> Int { // CHECK-NEXT: [[@LINE]]:27 -> {{[0-9]+}}:2 : 0
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE]]:15 : 0
|
||
return 0 // CHECK-NEXT: [[@LINE-1]]:16 -> [[@LINE+1]]:4 : 1
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+3]]:4 : (0 - 1)
|
||
struct S: Error {}
|
||
throw S()
|
||
}
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo6
|
||
func foo6(_ x: Int?) -> Int? { // CHECK-NEXT: [[@LINE]]:30 -> {{[0-9]+}}:2 : 0
|
||
if let x = x { // CHECK-NEXT: [[@LINE]]:16 -> [[@LINE+2]]:4 : 1
|
||
return x
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : (0 - 1)
|
||
return nil
|
||
}
|
||
} // CHECK-NEXT: }
|
||
|
||
// rdar://104078910, rdar://104079242 - Make sure the else if condition and the
|
||
// else gets a correct counter here.
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo7
|
||
func foo7() -> Int { // CHECK-NEXT: [[@LINE]]:20 -> [[@LINE+12]]:2 : 0
|
||
let x: Int
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE]]:15 : 0
|
||
x = 0 // CHECK-NEXT: [[@LINE-1]]:16 -> [[@LINE+1]]:4 : 1
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : (0 - 1)
|
||
x = 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 2
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : ((0 - 1) - 2)
|
||
x = 2 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 3
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : (((0 - 1) - 2) - 3)
|
||
x = 3
|
||
}
|
||
return x
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo8
|
||
func foo8() -> Int { // CHECK-NEXT: [[@LINE]]:20 -> [[@LINE+12]]:2 : 0
|
||
let x: Int // CHECK-NEXT: [[@LINE+1]]:6 -> [[@LINE+1]]:15 : 0
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:16 -> [[@LINE+2]]:4 : 1
|
||
return 0
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : (0 - 1)
|
||
x = 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 2
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : ((0 - 1) - 2)
|
||
x = 2 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 3
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : (((0 - 1) - 2) - 3)
|
||
x = 3
|
||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : (0 - 1)
|
||
return x
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo9
|
||
func foo9() -> Int { // CHECK-NEXT: [[@LINE]]:20 -> [[@LINE+12]]:2 : 0
|
||
let x: Int // CHECK-NEXT: [[@LINE+1]]:6 -> [[@LINE+1]]:15 : 0
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:16 -> [[@LINE+2]]:4 : 1
|
||
return 0
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : (0 - 1)
|
||
return 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 2
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : ((0 - 1) - 2)
|
||
x = 2 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 3
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : (((0 - 1) - 2) - 3)
|
||
x = 3
|
||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : ((0 - 1) - 2)
|
||
return x
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo10
|
||
func foo10() -> Int { // CHECK-NEXT: [[@LINE]]:21 -> [[@LINE+12]]:2 : 0
|
||
let x: Int // CHECK-NEXT: [[@LINE+1]]:6 -> [[@LINE+1]]:15 : 0
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:16 -> [[@LINE+2]]:4 : 1
|
||
return 0
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : (0 - 1)
|
||
return 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 2
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : ((0 - 1) - 2)
|
||
x = 2 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 3
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : (((0 - 1) - 2) - 3)
|
||
return 3
|
||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : 3
|
||
return x
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo11
|
||
func foo11() -> Int { // CHECK-NEXT: [[@LINE]]:21 -> [[@LINE+12]]:2 : 0
|
||
let x: Int // CHECK-NEXT: [[@LINE+1]]:6 -> [[@LINE+1]]:15 : 0
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:16 -> [[@LINE+2]]:4 : 1
|
||
x = 0
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : (0 - 1)
|
||
x = 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 2
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : ((0 - 1) - 2)
|
||
x = 2 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 3
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : (((0 - 1) - 2) - 3)
|
||
return 3
|
||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : ((1 + 2) + 3)
|
||
return x
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo12
|
||
func foo12() -> Int { // CHECK-NEXT: [[@LINE]]:21 -> [[@LINE+9]]:2 : 0
|
||
let x: Int
|
||
y: if .random() { // CHECK-NEXT: [[@LINE]]:9 -> [[@LINE]]:18 : 0
|
||
x = 0 // CHECK-NEXT: [[@LINE-1]]:19 -> [[@LINE+2]]:4 : 1
|
||
break y
|
||
} else {
|
||
x = 1 // CHECK-NEXT: [[@LINE-1]]:10 -> [[@LINE+1]]:4 : (0 - 1)
|
||
}
|
||
return x
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo13
|
||
func foo13() -> Int { // CHECK-NEXT: [[@LINE]]:21 -> [[@LINE+10]]:2 : 0
|
||
let x: Int
|
||
y: if .random() { // CHECK-NEXT: [[@LINE]]:9 -> [[@LINE]]:18 : 0
|
||
x = 0 // CHECK-NEXT: [[@LINE-1]]:19 -> [[@LINE+2]]:4 : 1
|
||
break y
|
||
} else {
|
||
x = 1 // CHECK-NEXT: [[@LINE-1]]:10 -> [[@LINE+2]]:4 : (0 - 1)
|
||
break y
|
||
}
|
||
return x
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo14
|
||
func foo14() -> Int { // CHECK-NEXT: [[@LINE]]:21 -> [[@LINE+14]]:2 : 0
|
||
let x: Int // CHECK-NEXT: [[@LINE+1]]:9 -> [[@LINE+1]]:18 : 0
|
||
y: if .random() { // CHECK-NEXT: [[@LINE]]:19 -> [[@LINE+3]]:4 : 1
|
||
x = 0
|
||
break y
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : (0 - 1)
|
||
return 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+1]]:4 : 2
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : ((0 - 1) - 2)
|
||
x = 2 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+2]]:4 : 3
|
||
break y
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : (((0 - 1) - 2) - 3)
|
||
return 3
|
||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : (1 + 3)
|
||
return x
|
||
} // CHECK-NEXT: }
|
||
|
||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_if.foo15
|
||
func foo15() -> Int { // CHECK-NEXT: [[@LINE]]:21 -> [[@LINE+19]]:2 : 0
|
||
let x: Int // CHECK-NEXT: [[@LINE+1]]:9 -> [[@LINE+1]]:18 : 0
|
||
y: if .random() { // CHECK-NEXT: [[@LINE]]:19 -> [[@LINE+5]]:4 : 1
|
||
x = 0
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE]]:17 : 1
|
||
break y // CHECK-NEXT: [[@LINE-1]]:18 -> [[@LINE+1]]:6 : 2
|
||
} // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE+1]]:4 : (1 - 2)
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : (0 - 1)
|
||
x = 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+4]]:4 : 3
|
||
if .random() { // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE]]:17 : 3
|
||
return 1 // CHECK-NEXT: [[@LINE-1]]:18 -> [[@LINE+1]]:6 : 4
|
||
} // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE+1]]:4 : (3 - 4)
|
||
} else if .random() { // CHECK-NEXT: [[@LINE]]:13 -> [[@LINE]]:22 : ((0 - 1) - 3)
|
||
x = 2 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+2]]:4 : 5
|
||
break y
|
||
} else { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : (((0 - 1) - 3) - 5)
|
||
return 3
|
||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : (((1 + 3) + 5) - 4)
|
||
return x
|
||
} // CHECK-NEXT: }
|