diff options
author | Dan Willemsen <dwillemsen@google.com> | 2022-03-29 00:50:59 -0700 |
---|---|---|
committer | Dan Willemsen <dwillemsen@google.com> | 2022-03-29 00:52:27 -0700 |
commit | f10932f763d058b0dcb3acfb795c869996fef47b (patch) | |
tree | 7e04d345c214f3efac3c4b86c7ec3e831c500437 /go/ssa/interp/ops.go | |
parent | d6d1ab63f7e2d16fb9a1f1d29755d12da90aa0bb (diff) | |
parent | e693fb417253d14786976bd29a456961aa8b6343 (diff) | |
download | golang-x-tools-f10932f763d058b0dcb3acfb795c869996fef47b.tar.gz |
Merge commit 'e693fb417253d14786976bd29a456961aa8b6343'
Change-Id: I65e50880732e718fa2264e47ef7cc19e37cc2f05
Diffstat (limited to 'go/ssa/interp/ops.go')
-rw-r--r-- | go/ssa/interp/ops.go | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/go/ssa/interp/ops.go b/go/ssa/interp/ops.go index 6af7847c0..3bc6a4e32 100644 --- a/go/ssa/interp/ops.go +++ b/go/ssa/interp/ops.go @@ -137,6 +137,26 @@ func asUint64(x value) uint64 { panic(fmt.Sprintf("cannot convert %T to uint64", x)) } +// asUnsigned returns the value of x, which must be an integer type, as its equivalent unsigned type, +// and returns true if x is non-negative. +func asUnsigned(x value) (value, bool) { + switch x := x.(type) { + case int: + return uint(x), x >= 0 + case int8: + return uint8(x), x >= 0 + case int16: + return uint16(x), x >= 0 + case int32: + return uint32(x), x >= 0 + case int64: + return uint64(x), x >= 0 + case uint, uint8, uint32, uint64, uintptr: + return x, true + } + panic(fmt.Sprintf("cannot convert %T to unsigned", x)) +} + // zero returns a new "zero" value of the specified type. func zero(t types.Type) value { switch t := t.(type) { @@ -576,7 +596,11 @@ func binop(op token.Token, t types.Type, x, y value) value { } case token.SHL: - y := asUint64(y) + u, ok := asUnsigned(y) + if !ok { + panic("negative shift amount") + } + y := asUint64(u) switch x.(type) { case int: return x.(int) << y @@ -603,7 +627,11 @@ func binop(op token.Token, t types.Type, x, y value) value { } case token.SHR: - y := asUint64(y) + u, ok := asUnsigned(y) + if !ok { + panic("negative shift amount") + } + y := asUint64(u) switch x.(type) { case int: return x.(int) >> y |