Add support for handling abnormal control flow
Go exposes "abnormal" control flow primitives, such as the following
- defer
- panic
- recover
- os.Exit
- log.Fatal
Currently, NilAway reports false positives in these cases. We must ensure that NilAway's models account for the result of using these primitives.
Another case is (*testing.T).Fatal.
For example, I am getting a lot of false positives for
foo, err := Foo()
fatalIfErr(t, err)
foo.Bar
func fatalIfErr(t testing.TB, err error) {
t.Helper()
if err != nil {
t.Fatal(err)
}
}
One thing to consider here is that many production systems wrap built–in panic calls to have errors reported to some error tracking system. Case in point: Uber's own zap (Panic, Panicf, etc).
It would be cool if nilaway could recognise such wrappers automatically but even being able to supply a list of known terminal functions would be good enough (more than just stdlib's log.Fatal).
Also: runtime.Goexit which testing.T.FailNow (called by testing.T.Fatal) and testing.T.SkipNow use.
The support for terminal function calls should already be supported since ctrlflow analyzer correctly constructs the CFG if there is a call to such functions (include the wrappers) in the block. On top of that NilAway should be able to automatically recognize those functions.
Users using OSS drivers should be automatically covered. For bazel/nogo users, please wait for merge of https://github.com/golang/tools/pull/497 upstream (or apply that patch locally). Please let us know if NilAway is still not treating those functions correctly. 😄
This issue will be kept open, but only for tracking support for defer/recover now.
Addressed in PR #252 .