Skip to content

Commit 240ae7e

Browse files
cmd/vet: if a function modifies its args, it's not a print wrapper
Fixes #26486 Updates #26555 Change-Id: I402137b796e574e9b085ab54290d1b4ef73d3fcc Reviewed-on: https://go-review.googlesource.com/125039 Reviewed-by: Russ Cox <[email protected]>
1 parent 214f7ec commit 240ae7e

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

src/cmd/vet/print.go

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ type printfExport struct {
6868
var printfImported = make(map[string]map[string]int)
6969

7070
type printfWrapper struct {
71-
name string
72-
fn *ast.FuncDecl
73-
format *ast.Field
74-
args *ast.Field
75-
callers []printfCaller
76-
printfLike bool
71+
name string
72+
fn *ast.FuncDecl
73+
format *ast.Field
74+
args *ast.Field
75+
callers []printfCaller
76+
failed bool // if true, not a printf wrapper
7777
}
7878

7979
type printfCaller struct {
@@ -168,6 +168,33 @@ func findPrintfLike(pkg *Package) {
168168
for _, w := range wrappers {
169169
// Scan function for calls that could be to other printf-like functions.
170170
ast.Inspect(w.fn.Body, func(n ast.Node) bool {
171+
if w.failed {
172+
return false
173+
}
174+
175+
// TODO: Relax these checks; issue 26555.
176+
if assign, ok := n.(*ast.AssignStmt); ok {
177+
for _, lhs := range assign.Lhs {
178+
if match(lhs, w.format) || match(lhs, w.args) {
179+
// Modifies the format
180+
// string or args in
181+
// some way, so not a
182+
// simple wrapper.
183+
w.failed = true
184+
return false
185+
}
186+
}
187+
}
188+
if un, ok := n.(*ast.UnaryExpr); ok && un.Op == token.AND {
189+
if match(un.X, w.format) || match(un.X, w.args) {
190+
// Taking the address of the
191+
// format string or args,
192+
// so not a simple wrapper.
193+
w.failed = true
194+
return false
195+
}
196+
}
197+
171198
call, ok := n.(*ast.CallExpr)
172199
if !ok || len(call.Args) == 0 || !match(call.Args[len(call.Args)-1], w.args) {
173200
return true

src/cmd/vet/testdata/print.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ func PrintfTests() {
318318
l.Print("%d", 1) // ERROR "Print call has possible formatting directive %d"
319319
l.Printf("%d", "x") // ERROR "Printf format %d has arg \x22x\x22 of wrong type string"
320320
l.Println("%d", 1) // ERROR "Println call has possible formatting directive %d"
321+
322+
// Issue 26486
323+
dbg("", 1) // no error "call has arguments but no formatting directive"
321324
}
322325

323326
func someString() string { return "X" }
@@ -650,3 +653,11 @@ func UnexportedStringerOrError() {
650653
func DisableErrorForFlag0() {
651654
fmt.Printf("%0t", true)
652655
}
656+
657+
// Issue 26486.
658+
func dbg(format string, args ...interface{}) {
659+
if format == "" {
660+
format = "%v"
661+
}
662+
fmt.Printf(format, args...)
663+
}

0 commit comments

Comments
 (0)