mirror of
https://github.com/golang/go
synced 2024-11-18 20:04:52 -07:00
go/analysis/passes/printf: fix false negative with nested pointers
Pointers to compound objects (structs, slices, arrays, maps) are only followed by fmt if the pointer is at the top level of an argument. This is to minimise the chances of fmt running into loops. However, vet did not follow this rule. It likely doesn't help that fmt does not document that restriction well, which is being tracked in #28625. This change was originally made to cmd/vet as https://go-review.googlesource.com/c/147997. Updates #27672. Change-Id: I65944cf355baedb4578af57046e2bbfd3fe6a9dc Reviewed-on: https://go-review.googlesource.com/c/149319 Reviewed-by: Michael Matloob <matloob@golang.org> Run-TryBot: Michael Matloob <matloob@golang.org>
This commit is contained in:
parent
c921186869
commit
0a8e63141f
10
go/analysis/passes/printf/testdata/src/a/a.go
vendored
10
go/analysis/passes/printf/testdata/src/a/a.go
vendored
@ -237,7 +237,7 @@ func PrintfTests() {
|
|||||||
Printf("%T", someFunction) // ok: maybe someone wants to see the type
|
Printf("%T", someFunction) // ok: maybe someone wants to see the type
|
||||||
// Bug: used to recur forever.
|
// Bug: used to recur forever.
|
||||||
Printf("%p %x", recursiveStructV, recursiveStructV.next)
|
Printf("%p %x", recursiveStructV, recursiveStructV.next)
|
||||||
Printf("%p %x", recursiveStruct1V, recursiveStruct1V.next)
|
Printf("%p %x", recursiveStruct1V, recursiveStruct1V.next) // want `Printf format %x has arg recursiveStruct1V\.next of wrong type \*a\.RecursiveStruct2`
|
||||||
Printf("%p %x", recursiveSliceV, recursiveSliceV)
|
Printf("%p %x", recursiveSliceV, recursiveSliceV)
|
||||||
Printf("%p %x", recursiveMapV, recursiveMapV)
|
Printf("%p %x", recursiveMapV, recursiveMapV)
|
||||||
// Special handling for Log.
|
// Special handling for Log.
|
||||||
@ -678,6 +678,14 @@ func PointersToCompoundTypes() {
|
|||||||
|
|
||||||
intMap := map[int]int{3: 4}
|
intMap := map[int]int{3: 4}
|
||||||
fmt.Printf("%s", &intMap) // want `Printf format %s has arg &intMap of wrong type \*map\[int\]int`
|
fmt.Printf("%s", &intMap) // want `Printf format %s has arg &intMap of wrong type \*map\[int\]int`
|
||||||
|
|
||||||
|
type T2 struct {
|
||||||
|
X string
|
||||||
|
}
|
||||||
|
type T1 struct {
|
||||||
|
X *T2
|
||||||
|
}
|
||||||
|
fmt.Printf("%s\n", T1{&T2{"x"}}) // want `Printf format %s has arg T1{&T2{.x.}} of wrong type a\.T1`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Printf wrappers from external package
|
// Printf wrappers from external package
|
||||||
|
@ -108,9 +108,13 @@ func matchArgTypeInternal(pass *analysis.Pass, t printfArgType, typ types.Type,
|
|||||||
// Check whether the rest can print pointers.
|
// Check whether the rest can print pointers.
|
||||||
return t&argPointer != 0
|
return t&argPointer != 0
|
||||||
}
|
}
|
||||||
// If it's a pointer to a struct, array, slice, or map, that's
|
// If it's a top-level pointer to a struct, array, slice, or
|
||||||
// equivalent in our analysis to whether we can print the type
|
// map, that's equivalent in our analysis to whether we can
|
||||||
// being pointed to.
|
// print the type being pointed to. Pointers in nested levels
|
||||||
|
// are not supported to minimize fmt running into loops.
|
||||||
|
if len(inProgress) > 1 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return matchArgTypeInternal(pass, t, under, arg, inProgress)
|
return matchArgTypeInternal(pass, t, under, arg, inProgress)
|
||||||
|
|
||||||
case *types.Struct:
|
case *types.Struct:
|
||||||
|
Loading…
Reference in New Issue
Block a user