From 5ba51116ee39a14a475d7f92a16dd676fccd0729 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Tue, 30 Jul 2013 14:00:52 +1000 Subject: [PATCH] go.tools/cmd/vet: treat arrays like slices in the printf checks. The analysis for types.Array was just missing. It's the same as a slice, but we can't share code easily because the types differ, so we just dup it. R=dsymonds CC=golang-dev https://golang.org/cl/12041045 --- cmd/vet/testdata/print.go | 21 +++++++++++++++++++++ cmd/vet/types.go | 15 ++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/cmd/vet/testdata/print.go b/cmd/vet/testdata/print.go index f41e7543..0440e348 100644 --- a/cmd/vet/testdata/print.go +++ b/cmd/vet/testdata/print.go @@ -79,9 +79,15 @@ func PrintfTests() { fmt.Printf("%X %X %X %X", 3, i, "hi", s) fmt.Printf("%.*s %d %g", 3, "hi", 23, 2.3) fmt.Printf("%s", &stringerv) + fmt.Printf("%v", &stringerv) fmt.Printf("%T", &stringerv) fmt.Printf("%v", notstringerv) fmt.Printf("%T", notstringerv) + fmt.Printf("%q", stringerarrayv) + fmt.Printf("%v", stringerarrayv) + fmt.Printf("%s", stringerarrayv) + fmt.Printf("%v", notstringerarrayv) + fmt.Printf("%T", notstringerarrayv) fmt.Printf("%*%", 2) // Ridiculous but allowed. fmt.Printf("%g", 1+2i) @@ -111,6 +117,9 @@ func PrintfTests() { 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("%t", stringerarrayv) // ERROR "arg stringerarrayv for printf verb %t of wrong type" + fmt.Printf("%t", notstringerarrayv) // ERROR "arg notstringerarrayv for printf verb %t of wrong type" + fmt.Printf("%q", notstringerarrayv) // ERROR "arg notstringerarrayv for printf verb %q 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" @@ -206,3 +215,15 @@ func (*stringer) Warnf(int, string, ...interface{}) string { type notstringer struct{} var notstringerv notstringer + +type stringerarray [4]float64 + +func (stringerarray) String() string { + return "string" +} + +var stringerarrayv stringerarray + +type notstringerarray [4]float64 + +var notstringerarrayv notstringerarray diff --git a/cmd/vet/types.go b/cmd/vet/types.go index 263f8534..9fd00ee7 100644 --- a/cmd/vet/types.go +++ b/cmd/vet/types.go @@ -98,18 +98,27 @@ func (f *File) matchArgType(t printfArgType, typ types.Type, arg ast.Expr) bool return t&argPointer != 0 case *types.Map: - // Recurse: map[int]int matches %d. + // Recur: map[int]int matches %d. return t&argPointer != 0 || (f.matchArgType(t, typ.Key(), arg) && f.matchArgType(t, typ.Elem(), arg)) case *types.Chan: return t&argPointer != 0 - case *types.Slice: + case *types.Array: + // Same as slice. if types.IsIdentical(typ.Elem().Underlying(), types.Typ[types.Byte]) && t&argString != 0 { return true // %s matches []byte } - // Recurse: []int matches %d. + // Recur: []int matches %d. + return t&argPointer != 0 || f.matchArgType(t, typ.Elem(), arg) + + case *types.Slice: + // Same as array. + if types.IsIdentical(typ.Elem().Underlying(), types.Typ[types.Byte]) && t&argString != 0 { + return true // %s matches []byte + } + // Recur: []int matches %d. return t&argPointer != 0 || f.matchArgType(t, typ.Elem(), arg) case *types.Pointer: