Skip to content

Commit da3408b

Browse files
committed
go/analysis/passes/printf: elaborate the documentation
Fixes golang/go#66733 Change-Id: Idbd92f92bad0fcb9286fcb68c6109b42a9d84045 Reviewed-on: https://go-review.googlesource.com/c/tools/+/578035 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Robert Findley <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 198a0a8 commit da3408b

File tree

3 files changed

+57
-40
lines changed

3 files changed

+57
-40
lines changed

go/analysis/passes/printf/doc.go

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,29 +11,73 @@
1111
//
1212
// The check applies to calls of the formatting functions such as
1313
// [fmt.Printf] and [fmt.Sprintf], as well as any detected wrappers of
14-
// those functions.
14+
// those functions such as [log.Printf]. It reports a variety of
15+
// mistakes such as syntax errors in the format string and mismatches
16+
// (of number and type) between the verbs and their arguments.
1517
//
16-
// In this example, the %d format operator requires an integer operand:
18+
// See the documentation of the fmt package for the complete set of
19+
// format operators and their operand types.
20+
//
21+
// # Examples
22+
//
23+
// The %d format operator requires an integer operand.
24+
// Here it is incorrectly applied to a string:
1725
//
1826
// fmt.Printf("%d", "hello") // fmt.Printf format %d has arg "hello" of wrong type string
1927
//
20-
// See the documentation of the fmt package for the complete set of
21-
// format operators and their operand types.
28+
// A call to Printf must have as many operands as there are "verbs" in
29+
// the format string, not too few:
30+
//
31+
// fmt.Printf("%d") // fmt.Printf format reads arg 1, but call has 0 args
32+
//
33+
// nor too many:
34+
//
35+
// fmt.Printf("%d", 1, 2) // fmt.Printf call needs 1 arg, but has 2 args
36+
//
37+
// Explicit argument indexes must be no greater than the number of
38+
// arguments:
39+
//
40+
// fmt.Printf("%[3]d", 1, 2) // fmt.Printf call has invalid argument index 3
41+
//
42+
// The checker also uses a heuristic to report calls to Print-like
43+
// functions that appear to have been intended for their Printf-like
44+
// counterpart:
45+
//
46+
// log.Print("%d", 123) // log.Print call has possible formatting directive %d
47+
//
48+
// # Inferred printf wrappers
49+
//
50+
// Functions that delegate their arguments to fmt.Printf are
51+
// considered "printf wrappers"; calls to them are subject to the same
52+
// checking. In this example, logf is a printf wrapper:
53+
//
54+
// func logf(level int, format string, args ...any) {
55+
// if enabled(level) {
56+
// log.Printf(format, args...)
57+
// }
58+
// }
59+
//
60+
// logf(3, "invalid request: %v") // logf format reads arg 1, but call has 0 args
2261
//
2362
// To enable printf checking on a function that is not found by this
2463
// analyzer's heuristics (for example, because control is obscured by
2564
// dynamic method calls), insert a bogus call:
2665
//
2766
// func MyPrintf(format string, args ...any) {
2867
// if false {
29-
// _ = fmt.Sprintf(format, args...) // enable printf checker
68+
// _ = fmt.Sprintf(format, args...) // enable printf checking
3069
// }
3170
// ...
3271
// }
3372
//
34-
// The -funcs flag specifies a comma-separated list of names of additional
35-
// known formatting functions or methods. If the name contains a period,
36-
// it must denote a specific function using one of the following forms:
73+
// # Specifying printf wrappers by flag
74+
//
75+
// The -funcs flag specifies a comma-separated list of names of
76+
// additional known formatting functions or methods. (This legacy flag
77+
// is rarely used due to the automatic inference described above.)
78+
//
79+
// If the name contains a period, it must denote a specific function
80+
// using one of the following forms:
3781
//
3882
// dir/pkg.Function
3983
// dir/pkg.Type.Method

gopls/doc/analyzers.md

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -553,40 +553,13 @@ printf: check consistency of Printf format strings and arguments
553553

554554
The check applies to calls of the formatting functions such as
555555
[fmt.Printf] and [fmt.Sprintf], as well as any detected wrappers of
556-
those functions.
557-
558-
In this example, the %d format operator requires an integer operand:
559-
560-
fmt.Printf("%d", "hello") // fmt.Printf format %d has arg "hello" of wrong type string
556+
those functions such as [log.Printf]. It reports a variety of
557+
mistakes such as syntax errors in the format string and mismatches
558+
(of number and type) between the verbs and their arguments.
561559

562560
See the documentation of the fmt package for the complete set of
563561
format operators and their operand types.
564562

565-
To enable printf checking on a function that is not found by this
566-
analyzer's heuristics (for example, because control is obscured by
567-
dynamic method calls), insert a bogus call:
568-
569-
func MyPrintf(format string, args ...any) {
570-
if false {
571-
_ = fmt.Sprintf(format, args...) // enable printf checker
572-
}
573-
...
574-
}
575-
576-
The -funcs flag specifies a comma-separated list of names of additional
577-
known formatting functions or methods. If the name contains a period,
578-
it must denote a specific function using one of the following forms:
579-
580-
dir/pkg.Function
581-
dir/pkg.Type.Method
582-
(*dir/pkg.Type).Method
583-
584-
Otherwise the name is interpreted as a case-insensitive unqualified
585-
identifier such as "errorf". Either way, if a listed name ends in f, the
586-
function is assumed to be Printf-like, taking a format string before the
587-
argument list. Otherwise it is assumed to be Print-like, taking a list
588-
of arguments with no format string.
589-
590563
[Full documentation](https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/printf)
591564

592565
**Enabled by default.**

gopls/internal/settings/api_json.go

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)