mirror of
https://github.com/golang/go.git
synced 2025-10-19 11:03:18 +00:00
cmd/compile: add tests for too-large shift amounts
Update #72018 Change-Id: I3188019658c37da3c31f06472023b39e13170ebf Reviewed-on: https://go-review.googlesource.com/c/go/+/654316 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
8abb8aa9a9
commit
f27d86c631
1 changed files with 203 additions and 0 deletions
|
@ -5,6 +5,7 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"math/bits"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
@ -1150,3 +1151,205 @@ func TestShiftOverflow(t *testing.T) {
|
|||
t.Errorf("got %d %d 0x%x, expected -32 -128 0x60", v, w, z)
|
||||
}
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func lsh64s(n int64, k int) int64 {
|
||||
return n << k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func lsh64u(n uint64, k int) uint64 {
|
||||
return n << k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func lsh32s(n int32, k int) int32 {
|
||||
return n << k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func lsh32u(n uint32, k int) uint32 {
|
||||
return n << k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func lsh16s(n int16, k int) int16 {
|
||||
return n << k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func lsh16u(n uint16, k int) uint16 {
|
||||
return n << k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func lsh8s(n int8, k int) int8 {
|
||||
return n << k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func lsh8u(n uint8, k int) uint8 {
|
||||
return n << k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func rsh64s(n int64, k int) int64 {
|
||||
return n >> k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func rsh64u(n uint64, k int) uint64 {
|
||||
return n >> k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func rsh32s(n int32, k int) int32 {
|
||||
return n >> k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func rsh32u(n uint32, k int) uint32 {
|
||||
return n >> k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func rsh16s(n int16, k int) int16 {
|
||||
return n >> k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func rsh16u(n uint16, k int) uint16 {
|
||||
return n >> k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func rsh8s(n int8, k int) int8 {
|
||||
return n >> k
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func rsh8u(n uint8, k int) uint8 {
|
||||
return n >> k
|
||||
}
|
||||
|
||||
func TestOverShiftLeft(t *testing.T) {
|
||||
for _, f := range []reflect.Value{
|
||||
reflect.ValueOf(lsh64s),
|
||||
reflect.ValueOf(lsh64u),
|
||||
reflect.ValueOf(lsh32s),
|
||||
reflect.ValueOf(lsh32u),
|
||||
reflect.ValueOf(lsh16s),
|
||||
reflect.ValueOf(lsh16u),
|
||||
reflect.ValueOf(lsh8s),
|
||||
reflect.ValueOf(lsh8u),
|
||||
} {
|
||||
typ := f.Type().In(0) // type of input/output
|
||||
one := reflect.ValueOf(1).Convert(typ)
|
||||
zero := reflect.ValueOf(0).Convert(typ).Interface()
|
||||
for k := 0; k < 100; k++ {
|
||||
got := f.Call([]reflect.Value{one, reflect.ValueOf(k)})[0].Interface()
|
||||
if k >= int(typ.Size()*8) {
|
||||
if got != zero {
|
||||
t.Errorf("shifted to zero prematurely: %s %d %v", typ, k, got)
|
||||
}
|
||||
} else {
|
||||
if got == zero {
|
||||
t.Errorf("shift doesn't result in zero: %s %d %v", typ, k, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverShiftRightU(t *testing.T) {
|
||||
for _, f := range []reflect.Value{
|
||||
reflect.ValueOf(rsh64u),
|
||||
reflect.ValueOf(rsh32u),
|
||||
reflect.ValueOf(rsh16u),
|
||||
reflect.ValueOf(rsh8u),
|
||||
} {
|
||||
typ := f.Type().In(0) // type of input/output
|
||||
max := reflect.ValueOf(uint64(1) << (typ.Size()*8 - 1)).Convert(typ)
|
||||
zero := reflect.ValueOf(0).Convert(typ).Interface()
|
||||
for k := 0; k < 100; k++ {
|
||||
got := f.Call([]reflect.Value{max, reflect.ValueOf(k)})[0].Interface()
|
||||
if k >= int(typ.Size()*8) {
|
||||
if got != zero {
|
||||
t.Errorf("shifted to zero prematurely: %s %d %v", typ, k, got)
|
||||
}
|
||||
} else {
|
||||
if got == zero {
|
||||
t.Errorf("shift doesn't result in zero: %s %d %v", typ, k, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestOverShiftRightS(t *testing.T) {
|
||||
for _, f := range []reflect.Value{
|
||||
reflect.ValueOf(rsh64s),
|
||||
reflect.ValueOf(rsh32s),
|
||||
reflect.ValueOf(rsh16s),
|
||||
reflect.ValueOf(rsh8s),
|
||||
} {
|
||||
typ := f.Type().In(0) // type of input/output
|
||||
maxInt := reflect.ValueOf(int64(1)<<(typ.Size()*8-1) - 1).Convert(typ)
|
||||
zero := reflect.ValueOf(0).Convert(typ).Interface()
|
||||
for k := 0; k < 100; k++ {
|
||||
got := f.Call([]reflect.Value{maxInt, reflect.ValueOf(k)})[0].Interface()
|
||||
if k < int(typ.Size()*8)-1 {
|
||||
if got == zero {
|
||||
t.Errorf("shifted to zero prematurely: %s %d %v", typ, k, got)
|
||||
}
|
||||
} else {
|
||||
if got != zero {
|
||||
t.Errorf("shift doesn't result in zero: %s %d %v", typ, k, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
minInt := reflect.ValueOf(int64(1) << (typ.Size()*8 - 1)).Convert(typ)
|
||||
negOne := reflect.ValueOf(-1).Convert(typ).Interface()
|
||||
for k := 0; k < 100; k++ {
|
||||
got := f.Call([]reflect.Value{minInt, reflect.ValueOf(k)})[0].Interface()
|
||||
if k < int(typ.Size()*8)-1 {
|
||||
if got == negOne {
|
||||
t.Errorf("shifted to negative one prematurely: %s %d %v", typ, k, got)
|
||||
}
|
||||
} else {
|
||||
if got != negOne {
|
||||
t.Errorf("shift doesn't result in negative one: %s %d %v", typ, k, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNegShifts(t *testing.T) {
|
||||
for i := 0; i < bits.UintSize; i++ {
|
||||
k := (-1) << i
|
||||
shouldPanic(func() { lsh64s(0, k) })
|
||||
shouldPanic(func() { lsh64u(0, k) })
|
||||
shouldPanic(func() { lsh32s(0, k) })
|
||||
shouldPanic(func() { lsh32u(0, k) })
|
||||
shouldPanic(func() { lsh16s(0, k) })
|
||||
shouldPanic(func() { lsh16u(0, k) })
|
||||
shouldPanic(func() { lsh8s(0, k) })
|
||||
shouldPanic(func() { lsh8u(0, k) })
|
||||
shouldPanic(func() { rsh64s(0, k) })
|
||||
shouldPanic(func() { rsh64u(0, k) })
|
||||
shouldPanic(func() { rsh32s(0, k) })
|
||||
shouldPanic(func() { rsh32u(0, k) })
|
||||
shouldPanic(func() { rsh16s(0, k) })
|
||||
shouldPanic(func() { rsh16u(0, k) })
|
||||
shouldPanic(func() { rsh8s(0, k) })
|
||||
shouldPanic(func() { rsh8u(0, k) })
|
||||
}
|
||||
}
|
||||
func shouldPanic(f func()) {
|
||||
defer func() {
|
||||
if recover() == nil {
|
||||
panic("not panicking")
|
||||
}
|
||||
}()
|
||||
f()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue