diff options
| author | Josh Bleecher Snyder <josharian@gmail.com> | 2017-02-28 10:29:58 -0800 |
|---|---|---|
| committer | Josh Bleecher Snyder <josharian@gmail.com> | 2017-02-28 19:13:18 +0000 |
| commit | d99d5f7caa10b679f8509c22aafb35a51ab716ae (patch) | |
| tree | 56b5c82af8de7a849fc45b982d8ded7e09984e8a /src/cmd/vet | |
| parent | 016569f204ed1c1060778b03ecacb33bc882d69a (diff) | |
| download | go-git-d99d5f7caa10b679f8509c22aafb35a51ab716ae.tar.gz | |
cmd/vet: allow shifts by amounts calculated using unsafe
The real world code that inspired this fix,
from runtime/pprof/map.go:
// Compute hash of (stk, tag).
h := uintptr(0)
for _, x := range stk {
h = h<<8 | (h >> (8 * (unsafe.Sizeof(h) - 1)))
h += uintptr(x) * 41
}
h = h<<8 | (h >> (8 * (unsafe.Sizeof(h) - 1)))
h += uintptr(tag) * 41
Change-Id: I99a95b97cba73811faedb0b9a1b9b54e9a1784a3
Reviewed-on: https://go-review.googlesource.com/37574
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/cmd/vet')
| -rw-r--r-- | src/cmd/vet/shift.go | 23 | ||||
| -rw-r--r-- | src/cmd/vet/testdata/shift.go | 5 |
2 files changed, 28 insertions, 0 deletions
diff --git a/src/cmd/vet/shift.go b/src/cmd/vet/shift.go index 55f3ea369f..83009ecff7 100644 --- a/src/cmd/vet/shift.go +++ b/src/cmd/vet/shift.go @@ -47,6 +47,29 @@ func checkLongShift(f *File, node ast.Node, x, y ast.Expr) { // like ^uint(0) >> 63 for 32/64 bit detection and compatibility. return } + + // Ignore shifts where the shift amount is calculated using unsafe. + // These are used for bit-twiddling tricks. + var hasUnsafe bool + ast.Inspect(y, func(n ast.Node) bool { + sel, ok := n.(*ast.SelectorExpr) + if !ok { + return true + } + pkg, ok := sel.X.(*ast.Ident) + if !ok { + return true + } + if pkg.Name == "unsafe" { + hasUnsafe = true + return false + } + return true + }) + if hasUnsafe { + return + } + v := f.pkg.types[y].Value if v == nil { return diff --git a/src/cmd/vet/testdata/shift.go b/src/cmd/vet/testdata/shift.go index 99acaadf6d..50d628d2c4 100644 --- a/src/cmd/vet/testdata/shift.go +++ b/src/cmd/vet/testdata/shift.go @@ -6,6 +6,8 @@ package testdata +import "unsafe" + func ShiftTest() { var i8 int8 _ = i8 << 7 @@ -77,4 +79,7 @@ func ShiftTest() { p >>= 32 // ERROR "p might be too small for shift of 32" const oneIf64Bit = ^uint(0) >> 63 // allow large shifts of constants; they are used for 32/64 bit compatibility tricks + + var h uintptr + h = h<<8 | (h >> (8 * (unsafe.Sizeof(h) - 1))) // shifts by unsafe amounts are safe } |
