summaryrefslogtreecommitdiff
path: root/src/cmd/vet
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2017-02-28 10:29:58 -0800
committerJosh Bleecher Snyder <josharian@gmail.com>2017-02-28 19:13:18 +0000
commitd99d5f7caa10b679f8509c22aafb35a51ab716ae (patch)
tree56b5c82af8de7a849fc45b982d8ded7e09984e8a /src/cmd/vet
parent016569f204ed1c1060778b03ecacb33bc882d69a (diff)
downloadgo-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.go23
-rw-r--r--src/cmd/vet/testdata/shift.go5
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
}