-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
The shift pass rejects a uint64 shifted by a constant 64, and on 32 bit platforms a uint shifted by 32, both of which come up in correct code. Here are two examples:
From a recent x/sys/unix CL:
func offs2lohi(offs int64) (lo, hi uintptr) {
const longBits = SizeofLong * 8
return uintptr(offs), uintptr(uint64(offs) >> longBits)
}
On a 64-bit system, the goal is to return offs, 0, and that expression does that, using a uint64 >> 64 in the second expression. I am going to send a CL out replacing >> longBits with >> (longBits - 1) >> 1, to make older vets happy with this code.
From a recent math/big CL:
// bits.Len uses a lookup table for the low-order bits on some
// architectures. Neutralize any input-dependent behavior by setting all
// bits after the first one bit.
top := uint(x[i])
top |= top >> 1
top |= top >> 2
top |= top >> 4
top |= top >> 8
top |= top >> 16
top |= top >> 16 >> 16 // ">> 32" doesn't compile on 32-bit architectures
return i*_W + bits.Len(top)
Note the comment says "doesn't compile" but really the problem is that it doesn't vet.
Vet should not be redefining what is permitted in the language for valid code. Because these programs are valid, we should loosen the check in passes/shift/shift.go to be amt > maxSize, not amt >= maxSize.