Skip to content

Commit 44e71e5

Browse files
committed
go/analysis/passes/printf: check anonymous functions too
This change causes the printf analyzer to consider anonymous functions that are directly assigned to a variable, such as printf := func(format string, args ...any) { ... } to be analyzed the same way as an ordinary function. This allows mistakes calling local printf-wrapper functions to be reported. We denote printf-like functions by a types.Object (which may be a *Func or, now, a *Var) throughout the algorithm. This generalizes to local and global vars and struct fields, even ones imported from another package, though since one cannot export a fact for foreign symbols, the imported var will only have the wrapper property within the unit that encloses the assignment. Also: - a number of clarifications to identifier names, comments, etc: - fix a couple of latent printf bugs in x/tools. + tests Change-Id: I82c23dae4a682b574c2b0f4e6daa9be260ae47be Reviewed-on: https://go-review.googlesource.com/c/tools/+/706635 Reviewed-by: Robert Findley <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 9095e9b commit 44e71e5

File tree

6 files changed

+378
-147
lines changed

6 files changed

+378
-147
lines changed

go/analysis/passes/nilness/nilness.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func runFunc(pass *analysis.Pass, fn *ssa.Function) {
5252
// notNil reports an error if v is provably nil.
5353
notNil := func(stack []fact, instr ssa.Instruction, v ssa.Value, descr string) {
5454
if nilnessOf(stack, v) == isnil {
55-
reportf("nilderef", instr.Pos(), descr)
55+
reportf("nilderef", instr.Pos(), "%s", descr)
5656
}
5757
}
5858

go/analysis/passes/printf/doc.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@
8282
// ...
8383
// }
8484
//
85+
// A local function may also be inferred as a printf wrapper. If it
86+
// is assigned to a variable, each call made through that variable will
87+
// be checked just like a call to a function:
88+
//
89+
// logf := func(format string, args ...any) {
90+
// message := fmt.Sprintf(format, args...)
91+
// log.Printf("%s: %s", prefix, message)
92+
// }
93+
// logf("%s", 123) // logf format %s has arg 123 of wrong type int
94+
//
8595
// # Specifying printf wrappers by flag
8696
//
8797
// The -funcs flag specifies a comma-separated list of names of

0 commit comments

Comments
 (0)