]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/vet: report uncalled functions in Printf %v
authorRuss Cox <rsc@golang.org>
Fri, 29 Jan 2016 15:16:24 +0000 (10:16 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 29 Jan 2016 17:01:47 +0000 (17:01 +0000)
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>
src/cmd/vet/print.go
src/cmd/vet/testdata/print.go

index 5436c5bf04b5b486a2e94322ea25201c713158c6..a16e864cad212df7fc5480b736037c6d448e7fda 100644 (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()
                }
index beeb642f2ad19dbf07c6f393d4bc922501df1b60..c5faa36e897a957d57e237b4fea8113ecdc89382 100644 (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)