1
0
mirror of https://github.com/golang/go synced 2024-11-23 23:40:13 -07:00

cmd/vet: report uncalled functions in Printf %v

Given, say, var f *os.File, a new vet check in CL 14122 diagnoses:

	fmt.Printf("%s\n", f.Name)
	fmt.Println(f.Name)

but not

	fmt.Printf("%v\n", f.Name)

In all three cases the error is that the argument should be f.Name().

Diagnosing Println but not Printf %v seems oddly inconsistent,
so I changed %v to have the check too. In fact, all verbs now have
the check except %p and %T.

Fixes Dave Cheney's confusion when trying to write an example
of the new vet check advertised in the Go 1.6 release notes.

Change-Id: I92fa6a7a1d5d9339a6a59ae4e587a254e633f500
Reviewed-on: https://go-review.googlesource.com/19101
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
Russ Cox 2016-01-29 10:16:24 -05:00
parent 2e08694d51
commit 0f89efa255
2 changed files with 7 additions and 4 deletions

View File

@ -445,12 +445,12 @@ func (f *File) okPrintfArg(call *ast.CallExpr, state *formatState) (ok bool) {
return false
}
arg := call.Args[argNum]
if f.isFunctionValue(arg) && state.verb != 'p' && state.verb != 'T' {
f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
return false
}
if !f.matchArgType(v.typ, nil, arg) {
typeString := ""
if f.isFunctionValue(arg) {
f.Badf(call.Pos(), "arg %s in printf call is a function value, not a function call", f.gofmt(arg))
return false
}
if typ := f.pkg.types[arg].Type; typ != nil {
typeString = typ.String()
}

View File

@ -197,7 +197,10 @@ func PrintfTests() {
et5.error() // ok, not an error method.
// Can't print a function.
Printf("%d", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
Printf("%v", someFunction) // ERROR "arg someFunction in printf call is a function value, not a function call"
Println(someFunction) // ERROR "arg someFunction in Println call is a function value, not a function call"
Printf("%p", someFunction) // ok: maybe someone wants to see the pointer
Printf("%T", someFunction) // ok: maybe someone wants to see the type
// Bug: used to recur forever.
Printf("%p %x", recursiveStructV, recursiveStructV.next)
Printf("%p %x", recursiveStruct1V, recursiveStruct1V.next)