From 92d8274bd7b8a4c65f24bafe401a029e58392704 Mon Sep 17 00:00:00 2001 From: Alan Donovan Date: Thu, 8 Nov 2018 16:54:54 -0500 Subject: [PATCH] go/analysis/passes/printf: preload with facts for std lib This change adds to the list of standard library functions known to be print or printf wrappers. Although the printf Analyzer is capable of identifying wrapper functions in the standard library, some drivers (e.g. Bazel) do not apply analyzers to the standard packages. Really this is a bug in those drivers but it is not likely to be fixed for a while. Change-Id: I2032d0cb5fcb50e7b9933a75809becdd680380ec Reviewed-on: https://go-review.googlesource.com/c/148572 Run-TryBot: Alan Donovan TryBot-Result: Gobot Gobot Reviewed-by: Michael Matloob --- go/analysis/passes/printf/printf.go | 44 +++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/go/analysis/passes/printf/printf.go b/go/analysis/passes/printf/printf.go index 23f634fd98e..4b761e25b5b 100644 --- a/go/analysis/passes/printf/printf.go +++ b/go/analysis/passes/printf/printf.go @@ -277,18 +277,56 @@ func checkPrintfFwd(pass *analysis.Pass, w *printfWrapper, call *ast.CallExpr, k // or case-insensitive identifiers such as "errorf". // // The -funcs flag adds to this set. +// +// The set below includes facts for many important standard library +// functions, even though the analysis is capable of deducing that, for +// example, fmt.Printf forwards to fmt.Fprintf. We avoid relying on the +// driver applying analyzers to standard packages because "go vet" does +// not do so with gccgo, and nor do some other build systems. +// TODO(adonovan): eliminate the redundant facts once this restriction +// is lifted. +// var isPrint = stringSet{ "fmt.Errorf": true, "fmt.Fprint": true, "fmt.Fprintf": true, "fmt.Fprintln": true, - "fmt.Print": true, // technically these three - "fmt.Printf": true, // are redundant because they - "fmt.Println": true, // forward to Fprint{,f,ln} + "fmt.Print": true, + "fmt.Printf": true, + "fmt.Println": true, "fmt.Sprint": true, "fmt.Sprintf": true, "fmt.Sprintln": true, + "runtime/trace.Logf": true, + + "log.Print": true, + "log.Printf": true, + "log.Println": true, + "log.Fatal": true, + "log.Fatalf": true, + "log.Fatalln": true, + "log.Panic": true, + "log.Panicf": true, + "log.Panicln": true, + "(*log.Logger).Fatal": true, + "(*log.Logger).Fatalf": true, + "(*log.Logger).Fatalln": true, + "(*log.Logger).Panic": true, + "(*log.Logger).Panicf": true, + "(*log.Logger).Panicln": true, + "(*log.Logger).Print": true, + "(*log.Logger).Printf": true, + "(*log.Logger).Println": true, + + "(*testing.common).Error": true, + "(*testing.common).Errorf": true, + "(*testing.common).Fatal": true, + "(*testing.common).Fatalf": true, + "(*testing.common).Log": true, + "(*testing.common).Logf": true, + "(*testing.common).Skip": true, + "(*testing.common).Skipf": true, // *testing.T and B are detected by induction, but testing.TB is // an interface and the inference can't follow dynamic calls. "(testing.TB).Error": true,