Skip to content

Commit 98bebae

Browse files
committed
Encode more knowledge about standard library in ctrlflow analyzer
1 parent 7522327 commit 98bebae

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

go/analysis/passes/ctrlflow/ctrlflow.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,21 @@ func (c *CFGs) callMayReturn(call *ast.CallExpr) (r bool) {
188188
return false // panic never returns
189189
}
190190

191+
// "Some driver implementations (such as those based on Bazel and Blaze) do not
192+
// currently apply analyzers to packages of the standard library. Therefore, for
193+
// best results, analyzer authors should not rely on analysis facts being available
194+
// for standard packages." [1].
195+
// This means that we cannot rely on the noReturn fact being available for standard
196+
// library functions.
197+
// Therefore, here we check if the function is an intrinsic no-return function.
198+
//
199+
// [1]: https://pkg.go.dev/golang.org/x/tools/go/analysis
200+
if sel, ok := call.Fun.(*ast.SelectorExpr); ok {
201+
if fn, ok := c.pass.TypesInfo.ObjectOf(sel.Sel).(*types.Func); ok && isIntrinsicNoReturn(fn) {
202+
return false // intrinsic no-return functions
203+
}
204+
}
205+
191206
// Is this a static call? Also includes static functions
192207
// parameterized by a type. Such functions may or may not
193208
// return depending on the parameter type, but in some
@@ -227,5 +242,12 @@ func isIntrinsicNoReturn(fn *types.Func) bool {
227242
// Add functions here as the need arises, but don't allocate memory.
228243
path, name := fn.Pkg().Path(), fn.Name()
229244
return path == "syscall" && (name == "Exit" || name == "ExitProcess" || name == "ExitThread") ||
230-
path == "runtime" && name == "Goexit"
245+
(path == "runtime" && name == "Goexit") ||
246+
// Ideally we should not need to list the following functions since they
247+
// internally call the functions above. However, we will only know that _if_
248+
// we also analyze the standard library. For some driver implementations like
249+
// Bazel it would not do so currently. Therefore, we list them here.
250+
(path == "log" && (name == "Fatal" || name == "Fatalf")) ||
251+
(path == "os" && (name == "Exit")) ||
252+
(path == "testing" && (name == "FailNow" || name == "Skip" || name == "Skipf" || name == "SkipNow"))
231253
}

0 commit comments

Comments
 (0)