Commit 240ae7e3 authored by Ian Lance Taylor's avatar Ian Lance Taylor

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/125039Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 214f7ec5
......@@ -68,12 +68,12 @@ type printfExport struct {
var printfImported = make(map[string]map[string]int)
type printfWrapper struct {
name string
fn *ast.FuncDecl
format *ast.Field
args *ast.Field
callers []printfCaller
printfLike bool
name string
fn *ast.FuncDecl
format *ast.Field
args *ast.Field
callers []printfCaller
failed bool // if true, not a printf wrapper
}
type printfCaller struct {
......@@ -168,6 +168,33 @@ func findPrintfLike(pkg *Package) {
for _, w := range wrappers {
// Scan function for calls that could be to other printf-like functions.
ast.Inspect(w.fn.Body, func(n ast.Node) bool {
if w.failed {
return false
}
// TODO: Relax these checks; issue 26555.
if assign, ok := n.(*ast.AssignStmt); ok {
for _, lhs := range assign.Lhs {
if match(lhs, w.format) || match(lhs, w.args) {
// Modifies the format
// string or args in
// some way, so not a
// simple wrapper.
w.failed = true
return false
}
}
}
if un, ok := n.(*ast.UnaryExpr); ok && un.Op == token.AND {
if match(un.X, w.format) || match(un.X, w.args) {
// Taking the address of the
// format string or args,
// so not a simple wrapper.
w.failed = true
return false
}
}
call, ok := n.(*ast.CallExpr)
if !ok || len(call.Args) == 0 || !match(call.Args[len(call.Args)-1], w.args) {
return true
......
......@@ -318,6 +318,9 @@ func PrintfTests() {
l.Print("%d", 1) // ERROR "Print call has possible formatting directive %d"
l.Printf("%d", "x") // ERROR "Printf format %d has arg \x22x\x22 of wrong type string"
l.Println("%d", 1) // ERROR "Println call has possible formatting directive %d"
// Issue 26486
dbg("", 1) // no error "call has arguments but no formatting directive"
}
func someString() string { return "X" }
......@@ -650,3 +653,11 @@ func UnexportedStringerOrError() {
func DisableErrorForFlag0() {
fmt.Printf("%0t", true)
}
// Issue 26486.
func dbg(format string, args ...interface{}) {
if format == "" {
format = "%v"
}
fmt.Printf(format, args...)
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment