package a // This file tests facts produced by ctrlflow. import ( "log" "os" "runtime" "syscall" "testing" "lib" ) var cond bool func a() { // want a:"noReturn" if cond { b() } else { for { } } } func b() { // want b:"noReturn" select {} } func f(x int) { // no fact here switch x { case 0: os.Exit(0) case 1: panic(0) } // default case returns } type T int func (T) method1() { // want method1:"noReturn" a() } func (T) method2() { // (may return) if cond { a() } } // Checking for the noreturn fact associated with F ensures that // ctrlflow proved each of the listed functions was "noReturn". // func standardFunctions(x int) { // want standardFunctions:"noReturn" t := new(testing.T) switch x { case 0: t.FailNow() case 1: t.Fatal() case 2: t.Fatalf("") case 3: t.Skip() case 4: t.SkipNow() case 5: t.Skipf("") case 6: log.Fatal() case 7: log.Fatalf("") case 8: log.Fatalln() case 9: os.Exit(0) case 10: syscall.Exit(0) case 11: runtime.Goexit() case 12: log.Panic() case 13: log.Panicln() case 14: log.Panicf("") default: panic(0) } } // False positives are possible. // This function is marked noReturn but in fact returns. // func spurious() { // want spurious:"noReturn" defer func() { recover() }() panic(nil) } func noBody() func g() { lib.CanReturn() } func h() { // want h:"noReturn" lib.NoReturn() }