mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Profiler] Fix throwing expressions in if conditions
Previously we would ignore the effect that an if statement or ternary's condition exit counter might have on its branches, as we assumed a condition can't do any control flow. However, in the case where the condition throws an error, we need to account for the error branch.
This commit is contained in:
@@ -11,8 +11,11 @@ struct S {
|
||||
func throwingMethod() throws -> Int { 0 }
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func throwingFn() throws -> Int { 0 }
|
||||
|
||||
func throwingBool() throws -> Bool { true }
|
||||
|
||||
var throwingProp: Int {
|
||||
get throws { 5 }
|
||||
}
|
||||
@@ -632,6 +635,186 @@ func test46() -> (Int, Int)? { // CHECK-NEXT: [[@LINE]]:30 -> [[@LINE+2]]:
|
||||
try? ({ throw SomeErr.Err1 }(), 0) // CHECK-NEXT: [[@LINE]]:33 -> [[@LINE]]:37 : (0 - 1)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test47yyKF"
|
||||
func test47() throws { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+2]]:2 : 0
|
||||
try throwingFn() // CHECK-NEXT: [[@LINE]]:19 -> [[@LINE+1]]:2 : (0 - 1)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test48SiyKF"
|
||||
func test48() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+5]]:2 : 0
|
||||
try throwingBool() // CHECK-NEXT: [[@LINE]]:21 -> [[@LINE+4]]:2 : (0 - 2)
|
||||
? try throwingFn() // CHECK-NEXT: [[@LINE]]:7 -> [[@LINE]]:23 : 1
|
||||
: 1 // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+2]]:2 : ((0 - 2) - 3)
|
||||
// CHECK-NEXT: [[@LINE-1]]:7 -> [[@LINE-1]]:8 : ((0 - 1) - 2)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test49SiyKF"
|
||||
func test49() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+6]]:2 : 0
|
||||
try throwingBool() // CHECK-NEXT: [[@LINE]]:21 -> [[@LINE+5]]:2 : (0 - 2)
|
||||
? try throwingFn() // CHECK-NEXT: [[@LINE]]:7 -> [[@LINE]]:23 : 1
|
||||
: try throwingFn() // CHECK-NEXT: [[@LINE-1]]:23 -> [[@LINE+3]]:2 : ((0 - 2) - 3)
|
||||
// CHECK-NEXT: [[@LINE-1]]:7 -> [[@LINE-1]]:23 : ((0 - 1) - 2)
|
||||
// CHECK-NEXT: [[@LINE-2]]:23 -> [[@LINE+1]]:2 : (((0 - 2) - 3) - 4)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test50SiyKF"
|
||||
func test50() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+8]]:2 : 0
|
||||
let x = if try throwingBool() { // CHECK-NEXT: [[@LINE]]:14 -> [[@LINE]]:32 : 0
|
||||
try throwingFn() // CHECK-NEXT: [[@LINE-1]]:32 -> [[@LINE+4]]:11 : (0 - 2)
|
||||
} else { // CHECK-NEXT: [[@LINE-2]]:33 -> [[@LINE]]:4 : 1
|
||||
1 // CHECK-NEXT: [[@LINE-2]]:21 -> [[@LINE-1]]:4 : (1 - 3)
|
||||
} // CHECK-NEXT: [[@LINE-2]]:4 -> [[@LINE+1]]:11 : ((0 - 2) - 3)
|
||||
return x // CHECK-NEXT: [[@LINE-3]]:10 -> [[@LINE-1]]:4 : ((0 - 1) - 2)
|
||||
// CHECK-NEXT: [[@LINE-2]]:4 -> [[@LINE-1]]:11 : ((0 - 2) - 3)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test51SiyKF"
|
||||
func test51() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+9]]:2 : 0
|
||||
let x = if try throwingBool() { // CHECK-NEXT: [[@LINE]]:14 -> [[@LINE]]:32 : 0
|
||||
try throwingFn() // CHECK-NEXT: [[@LINE-1]]:32 -> [[@LINE+4]]:11 : (0 - 2)
|
||||
} else { // CHECK-NEXT: [[@LINE-2]]:33 -> [[@LINE]]:4 : 1
|
||||
try throwingFn() // CHECK-NEXT: [[@LINE-2]]:21 -> [[@LINE-1]]:4 : (1 - 3)
|
||||
} // CHECK-NEXT: [[@LINE-2]]:4 -> [[@LINE+1]]:11 : ((0 - 2) - 3)
|
||||
return x // CHECK-NEXT: [[@LINE-3]]:10 -> [[@LINE-1]]:4 : ((0 - 1) - 2)
|
||||
// CHECK-NEXT: [[@LINE-3]]:21 -> [[@LINE-2]]:4 : (((0 - 1) - 2) - 4)
|
||||
// CHECK-NEXT: [[@LINE-3]]:4 -> [[@LINE-2]]:11 : (((0 - 2) - 3) - 4)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test52SiyKF"
|
||||
func test52() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+10]]:2 : 0
|
||||
let x = if try throwingBool(), // CHECK-NEXT: [[@LINE]]:14 -> [[@LINE]]:32 : 0
|
||||
try throwingBool() { // CHECK-NEXT: [[@LINE-1]]:32 -> [[@LINE+5]]:11 : (0 - 2)
|
||||
try throwingFn() // CHECK-NEXT: [[@LINE-1]]:32 -> [[@LINE+4]]:11 : ((0 - 2) - 3)
|
||||
} else { // CHECK-NEXT: [[@LINE-2]]:33 -> [[@LINE]]:4 : 1
|
||||
try throwingFn() // CHECK-NEXT: [[@LINE-2]]:21 -> [[@LINE-1]]:4 : (1 - 4)
|
||||
} // CHECK-NEXT: [[@LINE-2]]:4 -> [[@LINE+1]]:11 : (((0 - 2) - 3) - 4)
|
||||
return x // CHECK-NEXT: [[@LINE-3]]:10 -> [[@LINE-1]]:4 : (((0 - 1) - 2) - 3)
|
||||
// CHECK-NEXT: [[@LINE-3]]:21 -> [[@LINE-2]]:4 : ((((0 - 1) - 2) - 3) - 5)
|
||||
// CHECK-NEXT: [[@LINE-3]]:4 -> [[@LINE-2]]:11 : ((((0 - 2) - 3) - 4) - 5)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test53yyKF"
|
||||
func test53() throws { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+10]]:2 : 0
|
||||
if try throwingBool(), // CHECK-NEXT: [[@LINE]]:6 -> [[@LINE]]:24 : 0
|
||||
try throwingBool() { // CHECK-NEXT: [[@LINE-1]]:24 -> [[@LINE+8]]:2 : (0 - 2)
|
||||
try throwingFn() // CHECK-NEXT: [[@LINE-1]]:25 -> [[@LINE+7]]:2 : ((0 - 2) - 3)
|
||||
} else { // CHECK-NEXT: [[@LINE-2]]:26 -> [[@LINE]]:4 : 1
|
||||
try throwingFn() // CHECK-NEXT: [[@LINE-2]]:21 -> [[@LINE-1]]:4 : (1 - 4)
|
||||
} // CHECK-NEXT: [[@LINE-2]]:4 -> [[@LINE+4]]:2 : (((0 - 2) - 3) - 4)
|
||||
// CHECK-NEXT: [[@LINE-3]]:10 -> [[@LINE-1]]:4 : (((0 - 1) - 2) - 3)
|
||||
// CHECK-NEXT: [[@LINE-3]]:21 -> [[@LINE-2]]:4 : ((((0 - 1) - 2) - 3) - 5)
|
||||
// CHECK-NEXT: [[@LINE-3]]:4 -> [[@LINE+1]]:2 : ((((0 - 2) - 3) - 4) - 5)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test54SiSgyF"
|
||||
func test54()-> Int? { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+7]]:2 : 0
|
||||
if let x = try? throwingFn(),
|
||||
let y = try? throwingFn() { // CHECK-NEXT: [[@LINE]]:33 -> [[@LINE+2]]:4 : 1
|
||||
x + y // FIXME: This region is redundant, and not really accurate since we have implicit returns (rdar://118653218)
|
||||
} else { // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+3]]:2 : 0
|
||||
try? throwingFn() // CHECK-NEXT: [[@LINE-1]]:10 -> [[@LINE+1]]:4 : (0 - 1)
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:2 : 0
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test55yyKF"
|
||||
func test55() throws { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+5]]:2 : 0
|
||||
while try throwingBool() { // CHECK-NEXT: [[@LINE]]:9 -> [[@LINE]]:27 : (0 + 1)
|
||||
// CHECK-NEXT: [[@LINE-1]]:27 -> [[@LINE+3]]:2 : (0 - 2)
|
||||
// CHECK-NEXT: [[@LINE-2]]:28 -> [[@LINE+1]]:4 : 1
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:2 : (0 - 2)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// FIXME: The second condition ought to get a region too (rdar://118649481)
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test56yyKF"
|
||||
func test56() throws { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+6]]:2 : 0
|
||||
while try throwingBool(), // CHECK-NEXT: [[@LINE]]:9 -> [[@LINE]]:27 : (0 + 1)
|
||||
try throwingBool() { // CHECK-NEXT: [[@LINE-1]]:27 -> [[@LINE+4]]:2 : (0 - 2)
|
||||
// CHECK-NEXT: [[@LINE-1]]:27 -> [[@LINE+3]]:2 : ((0 - 2) - 3)
|
||||
// CHECK-NEXT: [[@LINE-2]]:28 -> [[@LINE+1]]:4 : 1
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:2 : ((0 - 2) - 3)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// FIXME: We ought to be giving both conditions a region here...
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test57yyF"
|
||||
func test57() { // CHECK-NEXT: [[@LINE]]:15 -> [[@LINE+4]]:2 : 0
|
||||
while let _ = try? throwingFn(),
|
||||
let _ = try? throwingFn() { // CHECK-NEXT: [[@LINE]]:35 -> [[@LINE+1]]:4 : 1
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:2 : 0
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// We generate the same regions for `try!` as `try`. We could handle it
|
||||
// specially, but the error branches are effectively unreachable, so it
|
||||
// doesn't make a difference.
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test58SiyF"
|
||||
func test58() -> Int { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+3]]:2 : 0
|
||||
let x = try! throwingFn() // CHECK-NEXT: [[@LINE]]:28 -> [[@LINE+1]]:11 : (0 - 1)
|
||||
return x
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test59SiyKF"
|
||||
func test59() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+5]]:2 : 0
|
||||
guard try throwingBool() else { // CHECK-NEXT: [[@LINE]]:27 -> [[@LINE+3]]:11 : (0 - 2)
|
||||
return 1 // CHECK-NEXT: [[@LINE-1]]:33 -> [[@LINE+1]]:4 : 1
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : ((0 - 1) - 2)
|
||||
return 0
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test60SiyKF"
|
||||
func test60() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+7]]:2 : 0
|
||||
switch try throwingBool() { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE]]:28 : 0
|
||||
case true: // CHECK-NEXT: [[@LINE-1]]:28 -> [[@LINE+5]]:2 : (0 - 1)
|
||||
return 0 // CHECK-NEXT: [[@LINE-1]]:3 -> [[@LINE]]:13 : 2
|
||||
case false: // CHECK-NEXT: [[@LINE]]:3 -> [[@LINE+1]]:13 : 3
|
||||
return 1
|
||||
}
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test61SiyKF"
|
||||
func test61() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+7]]:2 : 0
|
||||
switch try throwingBool() { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE]]:28 : 0
|
||||
case true: // CHECK-NEXT: [[@LINE-1]]:28 -> [[@LINE+5]]:2 : (0 - 1)
|
||||
0 // CHECK-NEXT: [[@LINE-1]]:3 -> [[@LINE]]:6 : 2
|
||||
case false: // CHECK-NEXT: [[@LINE]]:3 -> [[@LINE+1]]:6 : 3
|
||||
1 // FIXME: This next region shouldn't be needed, we should know it's unrechabale (rdar://118653218).
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:2 : (2 + 3)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test62SiyKF"
|
||||
func test62() throws -> Int { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+8]]:2 : 0
|
||||
let x = switch try throwingBool() { // CHECK-NEXT: [[@LINE]]:18 -> [[@LINE]]:36 : 0
|
||||
case true: // CHECK-NEXT: [[@LINE-1]]:36 -> [[@LINE+5]]:11 : (0 - 1)
|
||||
0 // CHECK-NEXT: [[@LINE-1]]:3 -> [[@LINE]]:6 : 2
|
||||
case false: // CHECK-NEXT: [[@LINE]]:3 -> [[@LINE+1]]:6 : 3
|
||||
1
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:11 : (2 + 3)
|
||||
return x
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test63yyKF"
|
||||
func test63() throws { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+4]]:2 : 0
|
||||
for _ in [try throwingFn()] { // CHECK-NEXT: [[@LINE]]:29 -> [[@LINE+3]]:2 : (0 - 2)
|
||||
// CHECK-NEXT: [[@LINE-1]]:31 -> [[@LINE+1]]:4 : 1
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:2 : (0 - 2)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// FIXME: We don't currently assign a separate region for the where clause, but
|
||||
// we ought to (rdar://118653191).
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test64yyKF"
|
||||
func test64() throws { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+5]]:2 : 0
|
||||
for _ in [0]
|
||||
where try throwingBool() { // CHECK-NEXT: [[@LINE]]:27 -> [[@LINE+3]]:2 : (0 - 2)
|
||||
// CHECK-NEXT: [[@LINE-1]]:28 -> [[@LINE+1]]:4 : 1
|
||||
} // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+1]]:2 : (0 - 2)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}} "$s15coverage_errors6test65yyKF"
|
||||
func test65() throws { // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE+5]]:2 : 0
|
||||
repeat { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+2]]:4 : 1
|
||||
// CHECK-NEXT: [[@LINE+1]]:4 -> [[@LINE+3]]:2 : 0
|
||||
} while try throwingBool() // CHECK-NEXT: [[@LINE]]:11 -> [[@LINE]]:29 : 1
|
||||
// CHECK-NEXT: [[@LINE-1]]:29 -> [[@LINE+1]]:2 : (0 - 2)
|
||||
} // CHECK-NEXT: }
|
||||
|
||||
struct TestInit {
|
||||
// CHECK-LABEL: sil_coverage_map {{.*}}// coverage_errors.TestInit.init() -> coverage_errors.TestInit
|
||||
init() { // CHECK-NEXT: [[@LINE]]:10 -> [[@LINE+5]]:4 : 0
|
||||
|
||||
Reference in New Issue
Block a user