cmd/compile: implement shifts by signed amounts

Allow shifts by signed amounts. Panic if the shift amount is negative.

TODO: We end up doing two compares per shift, see Ian's comment
https://github.com/golang/go/issues/19113#issuecomment-443241799 that
we could do it with a single comparison in the normal case.

The prove pass mostly handles this code well. For instance, it removes the
<0 check for cases like this:
    if s >= 0 { _ = x << s }
    _ = x << len(a)

This case isn't handled well yet:
    _ = x << (y & 0xf)
I'll do followon CLs for unhandled cases as needed.

Update #19113

R=go1.13

Change-Id: I839a5933d94b54ab04deb9dd5149f32c51c90fa1
Reviewed-on: https://go-review.googlesource.com/c/158719
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
This commit is contained in:
Keith Randall 2019-01-20 10:52:11 -08:00 committed by Keith Randall
parent e1acd854f7
commit 585c9e8412
10 changed files with 144 additions and 15 deletions

View file

@ -23,16 +23,16 @@ func panicCheckMalloc(err error) {
var indexError = error(errorString("index out of range"))
// The panicindex, panicslice, and panicdivide functions are called by
// The panic{index,slice,divide,shift} functions are called by
// code generated by the compiler for out of bounds index expressions,
// out of bounds slice expressions, and division by zero. The
// panicdivide (again), panicoverflow, panicfloat, and panicmem
// out of bounds slice expressions, division by zero, and shift by negative.
// The panicdivide (again), panicoverflow, panicfloat, and panicmem
// functions are called by the signal handler when a signal occurs
// indicating the respective problem.
//
// Since panicindex and panicslice are never called directly, and
// Since panic{index,slice,shift} are never called directly, and
// since the runtime package should never have an out of bounds slice
// or array reference, if we see those functions called from the
// or array reference or negative shift, if we see those functions called from the
// runtime package we turn the panic into a throw. That will dump the
// entire runtime stack for easier debugging.
@ -68,6 +68,16 @@ func panicoverflow() {
panic(overflowError)
}
var shiftError = error(errorString("negative shift amount"))
func panicshift() {
if hasPrefix(funcname(findfunc(getcallerpc())), "runtime.") {
throw(string(shiftError.(errorString)))
}
panicCheckMalloc(shiftError)
panic(shiftError)
}
var floatError = error(errorString("floating point error"))
func panicfloat() {