From 573374c476611d26a3422497bebb46a5a63ff7ba Mon Sep 17 00:00:00 2001 From: David Symonds Date: Tue, 30 Jul 2013 13:15:31 +1000 Subject: [PATCH] cmd/vet: Fix handling of non-Stringer arguments. First, %v and %T accept any arguments, so they should never warn. Second, pointer types were not handled in matchArgType. Third, the default response for matchArgType should be false. R=r CC=adonovan, golang-dev https://golang.org/cl/12038050 --- cmd/vet/testdata/print.go | 8 ++++++++ cmd/vet/types.go | 10 +++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/cmd/vet/testdata/print.go b/cmd/vet/testdata/print.go index 7a1b6714cf..f41e7543c5 100644 --- a/cmd/vet/testdata/print.go +++ b/cmd/vet/testdata/print.go @@ -80,6 +80,8 @@ func PrintfTests() { fmt.Printf("%.*s %d %g", 3, "hi", 23, 2.3) fmt.Printf("%s", &stringerv) fmt.Printf("%T", &stringerv) + fmt.Printf("%v", notstringerv) + fmt.Printf("%T", notstringerv) fmt.Printf("%*%", 2) // Ridiculous but allowed. fmt.Printf("%g", 1+2i) @@ -107,6 +109,8 @@ func PrintfTests() { fmt.Printf("%X", 2.3) // ERROR "arg 2.3 for printf verb %X of wrong type" fmt.Printf("%s", stringerv) // ERROR "arg stringerv for printf verb %s of wrong type" fmt.Printf("%t", stringerv) // ERROR "arg stringerv for printf verb %t of wrong type" + fmt.Printf("%q", notstringerv) // ERROR "arg notstringerv for printf verb %q of wrong type" + fmt.Printf("%t", notstringerv) // ERROR "arg notstringerv for printf verb %t of wrong type" fmt.Printf("%.*s %d %g", 3, "hi", 23, 'x') // ERROR "arg 'x' for printf verb %g of wrong type" fmt.Println() // not an error fmt.Println("%s", "hi") // ERROR "possible formatting directive in Println call" @@ -198,3 +202,7 @@ func (*stringer) Warn(int, ...interface{}) string { func (*stringer) Warnf(int, string, ...interface{}) string { return "warnf" } + +type notstringer struct{} + +var notstringerv notstringer diff --git a/cmd/vet/types.go b/cmd/vet/types.go index 27ce46879f..bd43f955cd 100644 --- a/cmd/vet/types.go +++ b/cmd/vet/types.go @@ -75,6 +75,10 @@ var ( // may be printed with %d etc. if that is appropriate for their element // types.) func (f *File) matchArgType(t printfArgType, typ types.Type, arg ast.Expr) bool { + // %v, %T accept any argument type. + if t == anyType { + return true + } if typ == nil { // external call typ = f.pkg.types[arg] @@ -108,6 +112,9 @@ func (f *File) matchArgType(t printfArgType, typ types.Type, arg ast.Expr) bool // Recurse: []int matches %d. return t&argPointer != 0 || f.matchArgType(t, typ.Elem(), arg) + case *types.Pointer: + return t&argPointer != 0 + case *types.Basic: switch typ.Kind() { case types.UntypedBool, @@ -158,9 +165,6 @@ func (f *File) matchArgType(t printfArgType, typ types.Type, arg ast.Expr) bool return true // Probably a type check problem. } panic("unreachable") - - default: - return true } return false