mirror of https://github.com/golang/go.git
cmd/vet: fix some pointer false positives in printf
fmt's godoc reads:
For compound objects, the elements are printed using these
rules, recursively, laid out like this:
struct: {field0 field1 ...}
array, slice: [elem0 elem1 ...]
maps: map[key1:value1 key2:value2 ...]
pointer to above: &{}, &[], &map[]
That is, a pointer to a struct, array, slice, or map, can be correctly
printed by fmt if the type pointed to can be printed without issues.
vet was only following this rule for pointers to structs, omitting
arrays, slices, and maps. Fix that, and add tests for all the
combinations.
Updates #27672.
Change-Id: Ie61ebe1fffc594184f7b24d7dbf72d7d5de78309
Reviewed-on: https://go-review.googlesource.com/c/147758
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
ef2c486598
commit
edb2d1cbf2
|
|
@ -645,3 +645,29 @@ func dbg(format string, args ...interface{}) {
|
|||
}
|
||||
fmt.Printf(format, args...)
|
||||
}
|
||||
|
||||
func PointersToCompoundTypes() {
|
||||
stringSlice := []string{"a", "b"}
|
||||
fmt.Printf("%s", &stringSlice) // not an error
|
||||
|
||||
intSlice := []int{3, 4}
|
||||
fmt.Printf("%s", &intSlice) // ERROR "Printf format %s has arg &intSlice of wrong type \*\[\]int"
|
||||
|
||||
stringArray := [2]string{"a", "b"}
|
||||
fmt.Printf("%s", &stringArray) // not an error
|
||||
|
||||
intArray := [2]int{3, 4}
|
||||
fmt.Printf("%s", &intArray) // ERROR "Printf format %s has arg &intArray of wrong type \*\[2\]int"
|
||||
|
||||
stringStruct := struct{ F string }{"foo"}
|
||||
fmt.Printf("%s", &stringStruct) // not an error
|
||||
|
||||
intStruct := struct{ F int }{3}
|
||||
fmt.Printf("%s", &intStruct) // ERROR "Printf format %s has arg &intStruct of wrong type \*struct{F int}"
|
||||
|
||||
stringMap := map[string]string{"foo": "bar"}
|
||||
fmt.Printf("%s", &stringMap) // not an error
|
||||
|
||||
intMap := map[int]int{3: 4}
|
||||
fmt.Printf("%s", &intMap) // ERROR "Printf format %s has arg &intMap of wrong type \*map\[int\]int"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,12 +217,20 @@ func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Exp
|
|||
if t == argPointer {
|
||||
return true
|
||||
}
|
||||
// If it's pointer to struct, that's equivalent in our analysis to whether we can print the struct.
|
||||
if str, ok := typ.Elem().Underlying().(*types.Struct); ok {
|
||||
return f.matchStructArgType(t, str, arg, inProgress)
|
||||
under := typ.Elem().Underlying()
|
||||
switch under.(type) {
|
||||
case *types.Struct: // see below
|
||||
case *types.Array: // see below
|
||||
case *types.Slice: // see below
|
||||
case *types.Map: // see below
|
||||
default:
|
||||
// Check whether the rest can print pointers.
|
||||
return t&argPointer != 0
|
||||
}
|
||||
// Check whether the rest can print pointers.
|
||||
return t&argPointer != 0
|
||||
// If it's a pointer to a struct, array, slice, or map, that's
|
||||
// equivalent in our analysis to whether we can print the type
|
||||
// being pointed to.
|
||||
return f.matchArgTypeInternal(t, under, arg, inProgress)
|
||||
|
||||
case *types.Struct:
|
||||
return f.matchStructArgType(t, typ, arg, inProgress)
|
||||
|
|
|
|||
Loading…
Reference in New Issue