mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Turn on the noreturn diagnostic for cases where a reachable unreachable could be encountered. Previously, the diagnostic would not fire if the function was marked noreturn and any of its reachable unreachable calls were around. While this makes sense from a SILGen perspective (it Just Crashes tm), it is still wrong. We need to diagnose *everything* that has reachable unreachables.
147 lines
3.8 KiB
Swift
147 lines
3.8 KiB
Swift
// RUN: %target-swift-frontend %s -emit-sil -verify
|
|
|
|
func singleBlock() -> Int {
|
|
_ = 0
|
|
} // expected-error {{missing return in a function expected to return 'Int'}}
|
|
|
|
func singleBlock2() -> Int {
|
|
var y = 0
|
|
y += 1
|
|
} // expected-error {{missing return in a function expected to return 'Int'}}
|
|
|
|
enum NoCasesButNotNever {}
|
|
|
|
func diagnoseNoCaseEnumMissingReturn() -> NoCasesButNotNever {
|
|
} // expected-error {{function with uninhabited return type 'NoCasesButNotNever' is missing call to another never-returning function on all paths}}
|
|
|
|
func diagnoseNeverMissingBody() -> Never {
|
|
} // expected-error {{function with uninhabited return type 'Never' is missing call to another never-returning function on all paths}}
|
|
|
|
_ = { () -> Never in
|
|
}() // expected-error {{closure with uninhabited return type 'Never' is missing call to another never-returning function on all paths}}-
|
|
|
|
func diagnoseNeverWithBody(i : Int) -> Never {
|
|
if (i == -1) {
|
|
print("Oh no!")
|
|
} else {
|
|
switch i {
|
|
case 0:
|
|
exit()
|
|
case 1:
|
|
fatalError()
|
|
default:
|
|
repeat { } while true
|
|
}
|
|
}
|
|
} // expected-error {{function with uninhabited return type 'Never' is missing call to another never-returning function on all paths}}
|
|
|
|
class MyClassWithClosure {
|
|
var f : (_ s: String) -> String = { (_ s: String) -> String in } // expected-error {{missing return in a closure expected to return 'String'}}
|
|
}
|
|
|
|
func multipleBlocksSingleMissing(b: Bool) -> (String, Int) {
|
|
var y = 0
|
|
if b {
|
|
return ("a", 1)
|
|
} else if (y == 0) {
|
|
y += 1
|
|
}
|
|
} // expected-error {{missing return in a function expected to return '(String, Int)'}}
|
|
|
|
func multipleBlocksAllMissing(x: Int) -> Int {
|
|
var y : Int = x + 1
|
|
while (y > 0 ) {
|
|
y -= 1
|
|
break
|
|
}
|
|
var x = 0
|
|
x += 1
|
|
} // expected-error {{missing return in a function expected to return 'Int'}}
|
|
|
|
@_silgen_name("exit") func exit () -> Never
|
|
|
|
func diagnose_missing_return_in_the_else_branch(i: Bool) -> Int {
|
|
if (i) {
|
|
exit()
|
|
}
|
|
} // expected-error {{missing return in a function expected to return 'Int'}}
|
|
|
|
func diagnose_missing_return_no_error_after_noreturn(i: Bool) -> Int {
|
|
if (i) {
|
|
exit()
|
|
} else {
|
|
exit()
|
|
}
|
|
} // no error
|
|
|
|
class TuringMachine {
|
|
func halt() -> Never {
|
|
repeat { } while true
|
|
}
|
|
}
|
|
|
|
func diagnose_missing_return_no_error_after_noreturn_method() -> Int {
|
|
TuringMachine().halt()
|
|
} // no error
|
|
|
|
func whileLoop(flag: Bool) -> Int {
|
|
var b = 1
|
|
while (flag) {
|
|
if b == 3 {
|
|
return 3
|
|
}
|
|
b += 1
|
|
}
|
|
} //expected-error {{missing return in a function expected to return 'Int'}}
|
|
|
|
func whileTrueLoop() -> Int {
|
|
var b = 1
|
|
while (true) {
|
|
if b == 3 {
|
|
return 3
|
|
}
|
|
b += 1
|
|
} // no-error
|
|
}
|
|
|
|
func testUnreachableAfterNoReturn(x: Int) -> Int {
|
|
exit(); // expected-note{{a call to a never-returning function}}
|
|
return x; // expected-warning {{will never be executed}}
|
|
}
|
|
|
|
func testUnreachableAfterNoReturnInADifferentBlock() -> Int {
|
|
let x:Int = 5
|
|
if true { // expected-note {{condition always evaluates to true}}
|
|
exit();
|
|
}
|
|
return x; // expected-warning {{will never be executed}}
|
|
}
|
|
|
|
func testReachableAfterNoReturnInADifferentBlock(x: Int) -> Int {
|
|
if x == 5 {
|
|
exit();
|
|
}
|
|
return x; // no warning
|
|
}
|
|
|
|
func testUnreachableAfterNoReturnFollowedByACall() -> Int {
|
|
let x:Int = 5
|
|
exit(); // expected-note{{a call to a never-returning function}}
|
|
exit(); // expected-warning {{will never be executed}}
|
|
return x
|
|
}
|
|
|
|
func testUnreachableAfterNoReturnMethod() -> Int {
|
|
TuringMachine().halt(); // expected-note{{a call to a never-returning function}}
|
|
return 0; // expected-warning {{will never be executed}}
|
|
}
|
|
|
|
func testCleanupCodeEmptyTuple(fn: @autoclosure () -> Bool = false,
|
|
message: String = "",
|
|
file: String = #file,
|
|
line: Int = #line) {
|
|
if true {
|
|
exit()
|
|
}
|
|
} // no warning
|