diff --git a/gnovm/pkg/gnolang/nodes.go b/gnovm/pkg/gnolang/nodes.go index b18ed157ca6..8927eafcfb2 100644 --- a/gnovm/pkg/gnolang/nodes.go +++ b/gnovm/pkg/gnolang/nodes.go @@ -2119,6 +2119,7 @@ const ( ATTR_IOTA GnoAttribute = "ATTR_IOTA" ATTR_LOCATIONED GnoAttribute = "ATTR_LOCATIONED" ATTR_INJECTED GnoAttribute = "ATTR_INJECTED" + ATTR_SHIFT_RHS GnoAttribute = "ATTR_SHIFT_RHS" ) var rePkgName = regexp.MustCompile(`^[a-z][a-z0-9_]+$`) diff --git a/gnovm/pkg/gnolang/op_binary.go b/gnovm/pkg/gnolang/op_binary.go index db3c1e5695c..24123d285ad 100644 --- a/gnovm/pkg/gnolang/op_binary.go +++ b/gnovm/pkg/gnolang/op_binary.go @@ -1097,6 +1097,7 @@ func xorAssign(lv, rv *TypedValue) { // for doOpShl and doOpShlAssign. func shlAssign(lv, rv *TypedValue) { + rv.AssertNonNegative("runtime error: negative shift amount") // set the result in lv. // NOTE: baseOf(rv.T) is always UintType. switch baseOf(lv.T) { @@ -1136,6 +1137,7 @@ func shlAssign(lv, rv *TypedValue) { // for doOpShr and doOpShrAssign. func shrAssign(lv, rv *TypedValue) { + rv.AssertNonNegative("runtime error: negative shift amount") // set the result in lv. // NOTE: baseOf(rv.T) is always UintType. switch baseOf(lv.T) { diff --git a/gnovm/pkg/gnolang/op_call.go b/gnovm/pkg/gnolang/op_call.go index 15531ec610d..510c308a86a 100644 --- a/gnovm/pkg/gnolang/op_call.go +++ b/gnovm/pkg/gnolang/op_call.go @@ -27,6 +27,11 @@ func (m *Machine) doOpPrecall() { case TypeValue: // Do not pop type yet. // No need for frames. + xv := m.PeekValue(1) + if cx.GetAttribute(ATTR_SHIFT_RHS) == true { + xv.AssertNonNegative("runtime error: negative shift amount") + } + m.PushOp(OpConvert) if debug { if len(cx.Args) != 1 { diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 9168fc6f7c1..df1f7bab498 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -1025,7 +1025,7 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { isShift := n.Op == SHL || n.Op == SHR if isShift { // check LHS type compatibility - n.checkShiftLhs(lt) + n.assertShiftExprCompatible1(store, last, lt, rt) // checkOrConvert RHS if baseOf(rt) != UintType { // convert n.Right to (gno) uint type, @@ -1036,6 +1036,7 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { Op: n.Op, Right: rn, } + n2.Right.SetAttribute(ATTR_SHIFT_RHS, true) resn := Preprocess(store, last, n2) return resn, TRANS_CONTINUE } @@ -1097,12 +1098,34 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { // NOTE: binary operations are always computed in // gno, never with reflect. } else { - // convert n.Left to right type. - checkOrConvertType(store, last, &n.Left, rt, false) + // right is untyped const, left is not const, typed/untyped + checkUntypedShiftExpr := func(x Expr) { + if bx, ok := x.(*BinaryExpr); ok { + slt := evalStaticTypeOf(store, last, bx.Left) + if bx.Op == SHL || bx.Op == SHR { + srt := evalStaticTypeOf(store, last, bx.Right) + bx.assertShiftExprCompatible1(store, last, slt, srt) + } + } + } + + if !isUntyped(rt) { // right is typed + checkOrConvertType(store, last, &n.Left, rt, false) + } else { + if shouldSwapOnSpecificity(lt, rt) { + checkUntypedShiftExpr(n.Right) + } else { + checkUntypedShiftExpr(n.Left) + } + } } } else if lcx.T == nil { // LHS is nil. // convert n.Left to typed-nil type. checkOrConvertType(store, last, &n.Left, rt, false) + } else { + if isUntyped(rt) { + checkOrConvertType(store, last, &n.Right, lt, false) + } } } else if ric { // right is const, left is not if isUntyped(rcx.T) { @@ -1134,12 +1157,33 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { // NOTE: binary operations are always computed in // gno, never with reflect. } else { - // convert n.Right to left type. - checkOrConvertType(store, last, &n.Right, lt, false) + // right is untyped const, left is not const, typed or untyped + checkUntypedShiftExpr := func(x Expr) { + if bx, ok := x.(*BinaryExpr); ok { + if bx.Op == SHL || bx.Op == SHR { + srt := evalStaticTypeOf(store, last, bx.Right) + bx.assertShiftExprCompatible1(store, last, rt, srt) + } + } + } + // both untyped, e.g. 1<>=. convertType(store, last, &n.Rhs[0], UintType) } else if n.Op == ADD_ASSIGN || n.Op == SUB_ASSIGN || n.Op == MUL_ASSIGN || n.Op == QUO_ASSIGN || n.Op == REM_ASSIGN { @@ -2281,10 +2343,15 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { vt := evalStaticTypeOf(store, last, vx) sts[i] = vt } - } else { + } else { // T is nil, n not const // convert n.Value to default type. for i, vx := range n.Values { - convertIfConst(store, last, vx) + if cx, ok := vx.(*ConstExpr); ok { + convertConst(store, last, cx, nil) + // convertIfConst(store, last, vx) + } else { + checkOrConvertType(store, last, &vx, nil, false) + } vt := evalStaticTypeOf(store, last, vx) sts[i] = vt } @@ -2840,9 +2907,25 @@ func checkOrConvertType(store Store, last BlockNode, x *Expr, t Type, autoNative assertAssignableTo(cx.T, t, autoNative) } } else if bx, ok := (*x).(*BinaryExpr); ok && (bx.Op == SHL || bx.Op == SHR) { - // "push" expected type into shift binary's left operand. recursively. - checkOrConvertType(store, last, &bx.Left, t, autoNative) - } else if *x != nil { // XXX if x != nil && t != nil { + xt := evalStaticTypeOf(store, last, *x) + if debug { + debug.Printf("shift, xt: %v, Op: %v, t: %v \n", xt, bx.Op, t) + } + if isUntyped(xt) { + // check assignable first, see: types/shift_b6.gno + assertAssignableTo(xt, t, autoNative) + + if t == nil || t.Kind() == InterfaceKind { + t = defaultTypeOf(xt) + } + + bx.assertShiftExprCompatible2(t) + checkOrConvertType(store, last, &bx.Left, t, autoNative) + } else { + assertAssignableTo(xt, t, autoNative) + } + return + } else if *x != nil { xt := evalStaticTypeOf(store, last, *x) if t != nil { assertAssignableTo(xt, t, autoNative) @@ -2853,19 +2936,53 @@ func checkOrConvertType(store Store, last BlockNode, x *Expr, t Type, autoNative switch bx.Op { case ADD, SUB, MUL, QUO, REM, BAND, BOR, XOR, BAND_NOT, LAND, LOR: - // push t into bx.Left and bx.Right - checkOrConvertType(store, last, &bx.Left, t, autoNative) - checkOrConvertType(store, last, &bx.Right, t, autoNative) - return - case SHL, SHR: - // push t into bx.Left - checkOrConvertType(store, last, &bx.Left, t, autoNative) + lt := evalStaticTypeOf(store, last, bx.Left) + rt := evalStaticTypeOf(store, last, bx.Right) + if t != nil { + // push t into bx.Left and bx.Right + checkOrConvertType(store, last, &bx.Left, t, autoNative) + checkOrConvertType(store, last, &bx.Right, t, autoNative) + return + } else { + if shouldSwapOnSpecificity(lt, rt) { + // e.g. 1.0< string)) to type uint diff --git a/gnovm/tests/files/types/shift_a2.gno b/gnovm/tests/files/types/shift_a2.gno index 91072929306..726d5415b15 100644 --- a/gnovm/tests/files/types/shift_a2.gno +++ b/gnovm/tests/files/types/shift_a2.gno @@ -1,6 +1,5 @@ package main -// both typed(different) const func main() { println(1 << int(1)) println(1 >> int(1)) diff --git a/gnovm/tests/files/types/shift_a4.gno b/gnovm/tests/files/types/shift_a4.gno index 3561929b672..694d771f190 100644 --- a/gnovm/tests/files/types/shift_a4.gno +++ b/gnovm/tests/files/types/shift_a4.gno @@ -1,6 +1,5 @@ package main -// both typed(different) const func main() { println(1 << 1.0) println(1 >> 1.0) diff --git a/gnovm/tests/files/types/shift_a5.gno b/gnovm/tests/files/types/shift_a5.gno index a0b7652c6d1..5d2c4304732 100644 --- a/gnovm/tests/files/types/shift_a5.gno +++ b/gnovm/tests/files/types/shift_a5.gno @@ -1,10 +1,10 @@ package main -// TODO: support this? func main() { println(1.0 << 1) println(1.0 >> 1) } -// Error: -// main/files/types/shift_a5.gno:5:10: operator << not defined on: BigdecKind +// Output: +// 2 +// 0 diff --git a/gnovm/tests/files/types/shift_a7.gno b/gnovm/tests/files/types/shift_a7.gno index 62151c5cfc5..cd1b3d95ec7 100644 --- a/gnovm/tests/files/types/shift_a7.gno +++ b/gnovm/tests/files/types/shift_a7.gno @@ -6,4 +6,4 @@ func main() { } // Error: -// main/files/types/shift_a7.gno:3:1: cannot convert StringKind to UintKind +// main/files/types/shift_a7.gno:5:10: cannot convert (const ("a" string)) to type uint diff --git a/gnovm/tests/files/types/shift_b0.gno b/gnovm/tests/files/types/shift_b0.gno new file mode 100644 index 00000000000..fa9ee4ed2a0 --- /dev/null +++ b/gnovm/tests/files/types/shift_b0.gno @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + x := 2 + r := uint64(1 << x) + println(r) + fmt.Printf("%T \n", r) +} + +// Output: +// 4 +// uint64 diff --git a/gnovm/tests/files/types/shift_b1.gno b/gnovm/tests/files/types/shift_b1.gno new file mode 100644 index 00000000000..403887269c0 --- /dev/null +++ b/gnovm/tests/files/types/shift_b1.gno @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + x := 2 + r := uint64(1< bigint does not implement main.R (missing method foo) diff --git a/gnovm/tests/files/types/shift_b6a.gno b/gnovm/tests/files/types/shift_b6a.gno new file mode 100644 index 00000000000..26b7f1b2ea1 --- /dev/null +++ b/gnovm/tests/files/types/shift_b6a.gno @@ -0,0 +1,31 @@ +package main + +import "fmt" + +type R interface { + foo() +} + +type U64 uint64 + +func (u64 U64) foo() { + println("bar") +} + +func bar(r R) { + r.foo() +} + +func main() { + x := 2 + var r R + r = U64(1) << x + + r.foo() + + fmt.Printf("%T \n", r) // TODO: should output main.U64 rather than the underlying type +} + +// Output: +// bar +// uint64 diff --git a/gnovm/tests/files/types/shift_b7.gno b/gnovm/tests/files/types/shift_b7.gno new file mode 100644 index 00000000000..ccc6cd41b7f --- /dev/null +++ b/gnovm/tests/files/types/shift_b7.gno @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func main() { + x := 2 + r := float32(1<>2) +} + +// Output: +// 4 0 diff --git a/gnovm/tests/files/types/shift_c3.gno b/gnovm/tests/files/types/shift_c3.gno new file mode 100644 index 00000000000..6ca9a8b7cc2 --- /dev/null +++ b/gnovm/tests/files/types/shift_c3.gno @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + x := 1 + r := uint(+(1 << x)) + println(r) + fmt.Printf("%T \n", r) +} + +// Output: +// 2 +// uint diff --git a/gnovm/tests/files/types/shift_c4.gno b/gnovm/tests/files/types/shift_c4.gno new file mode 100644 index 00000000000..55b5fa782d7 --- /dev/null +++ b/gnovm/tests/files/types/shift_c4.gno @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + x := 63 + r := int32(+(1<>x) +} + +// Output: +// uint64 +// int64 +// 2048 +// 0 diff --git a/gnovm/tests/files/types/shift_d12.gno b/gnovm/tests/files/types/shift_d12.gno new file mode 100644 index 00000000000..3d8c6e3de16 --- /dev/null +++ b/gnovm/tests/files/types/shift_d12.gno @@ -0,0 +1,16 @@ +package main + +import "fmt" + +func foo(a uint64, b float32) { + fmt.Printf("%T \n", a) + println(a) +} + +func main() { + x := 11 + foo(1<>x) +} + +// Error: +// main/files/types/shift_d12.gno:12:2: operator >> not defined on: Float32Kind diff --git a/gnovm/tests/files/types/shift_d13.gno b/gnovm/tests/files/types/shift_d13.gno new file mode 100644 index 00000000000..0ab495c1a26 --- /dev/null +++ b/gnovm/tests/files/types/shift_d13.gno @@ -0,0 +1,17 @@ +package main + +import "fmt" + +// it's like assign +func foo(a uint64, b float32) { + fmt.Printf("%T \n", a) + println(a) +} + +func main() { + x := 11 + foo(1<>x) +} + +// Error: +// main/files/types/shift_d13.gno:13:2: cannot use int as float32 diff --git a/gnovm/tests/files/types/shift_d14.gno b/gnovm/tests/files/types/shift_d14.gno new file mode 100644 index 00000000000..cfeb643e291 --- /dev/null +++ b/gnovm/tests/files/types/shift_d14.gno @@ -0,0 +1,18 @@ +package main + +import "fmt" + +// it's like assign +func foo(a uint64, b int64) { + fmt.Printf("%T \n", a) + println(a) +} + +func main() { + x := 11 + foo(1<>x) +} + +// Output: +// uint64 +// 2048 diff --git a/gnovm/tests/files/types/shift_d15.gno b/gnovm/tests/files/types/shift_d15.gno new file mode 100644 index 00000000000..a29108aef5a --- /dev/null +++ b/gnovm/tests/files/types/shift_d15.gno @@ -0,0 +1,10 @@ +package main + +func main() { + x := 64 + y := uint64(1 << x) + println(y) +} + +// Output: +// 0 diff --git a/gnovm/tests/files/types/shift_d16.gno b/gnovm/tests/files/types/shift_d16.gno new file mode 100644 index 00000000000..3b7fb0aec50 --- /dev/null +++ b/gnovm/tests/files/types/shift_d16.gno @@ -0,0 +1,10 @@ +package main + +func main() { + x := 64 + y := uint64(1<>2) //special case with == !=, untyped bool + println(r) +} + +// Error: +// main/files/types/shift_d4.gno:4:7: cannot convert BoolKind to Uint64Kind diff --git a/gnovm/tests/files/types/shift_d40.gno b/gnovm/tests/files/types/shift_d40.gno new file mode 100644 index 00000000000..8840f8b7322 --- /dev/null +++ b/gnovm/tests/files/types/shift_d40.gno @@ -0,0 +1,10 @@ +package main + +func main() { + a := 2 + s := []float32{1 << a} + println(s[0]) +} + +// Error: +// main/files/types/shift_d40.gno:5:7: operator << not defined on: Float32Kind diff --git a/gnovm/tests/files/types/shift_d41.gno b/gnovm/tests/files/types/shift_d41.gno new file mode 100644 index 00000000000..bf46da524f7 --- /dev/null +++ b/gnovm/tests/files/types/shift_d41.gno @@ -0,0 +1,10 @@ +package main + +func main() { + a := 2 + s := map[string]float32{"k": 1 << a} + println(s["k"]) +} + +// Error: +// main/files/types/shift_d41.gno:5:7: operator << not defined on: Float32Kind diff --git a/gnovm/tests/files/types/shift_d42.gno b/gnovm/tests/files/types/shift_d42.gno new file mode 100644 index 00000000000..c2bbfe94e2b --- /dev/null +++ b/gnovm/tests/files/types/shift_d42.gno @@ -0,0 +1,14 @@ +package main + +func main() { + type S struct { + a float32 + } + s := S{ + a: 1 << 2, + } + println(s.a) +} + +// Output: +// 4 diff --git a/gnovm/tests/files/types/shift_d43.gno b/gnovm/tests/files/types/shift_d43.gno new file mode 100644 index 00000000000..e9b0032ac9a --- /dev/null +++ b/gnovm/tests/files/types/shift_d43.gno @@ -0,0 +1,10 @@ +package main + +func main() { + a := 2 + s := map[string]interface{}{"k": 1 << a} + println(s["k"]) +} + +// Output: +// 4 diff --git a/gnovm/tests/files/types/shift_d44.gno b/gnovm/tests/files/types/shift_d44.gno new file mode 100644 index 00000000000..0ef024f1e6b --- /dev/null +++ b/gnovm/tests/files/types/shift_d44.gno @@ -0,0 +1,10 @@ +package main + +func main() { + a := 1 + b := 1 + (a == b)++ // LHS is untyped bool, determined in preprocess +} + +// Error: +// main/files/types/shift_d44.gno:6:2: operator ++ not defined on: BoolKind diff --git a/gnovm/tests/files/types/shift_d45.gno b/gnovm/tests/files/types/shift_d45.gno new file mode 100644 index 00000000000..5c504d7d616 --- /dev/null +++ b/gnovm/tests/files/types/shift_d45.gno @@ -0,0 +1,10 @@ +package main + +func main() { + x := 11 + y := uint64(1 << x) + println(y) +} + +// Output: +// 2048 diff --git a/gnovm/tests/files/types/shift_d46.gno b/gnovm/tests/files/types/shift_d46.gno new file mode 100644 index 00000000000..8490c751c88 --- /dev/null +++ b/gnovm/tests/files/types/shift_d46.gno @@ -0,0 +1,10 @@ +package main + +func main() { + x := 11 + y := uint64(1.0 << x) + println(y) +} + +// Output: +// 2048 diff --git a/gnovm/tests/files/types/shift_d47.gno b/gnovm/tests/files/types/shift_d47.gno new file mode 100644 index 00000000000..d50c3944e90 --- /dev/null +++ b/gnovm/tests/files/types/shift_d47.gno @@ -0,0 +1,26 @@ +package main + +var specialBytes [16]byte + +func main() { + for i, b := range []byte(`\.+*?()|[]{}^$`) { + specialBytes[b%16] |= 1 << (b / 16) + println(i, (1 << (b / 16)), specialBytes[b%16]) + } +} + +// Output: +// 0 32 32 +// 1 4 4 +// 2 4 4 +// 3 4 4 +// 4 8 8 +// 5 4 4 +// 6 4 4 +// 7 128 160 +// 8 32 36 +// 9 32 32 +// 10 128 164 +// 11 128 160 +// 12 32 36 +// 13 4 4 diff --git a/gnovm/tests/files/types/shift_d48.gno b/gnovm/tests/files/types/shift_d48.gno new file mode 100644 index 00000000000..2ec6782c7f0 --- /dev/null +++ b/gnovm/tests/files/types/shift_d48.gno @@ -0,0 +1,23 @@ +package main + +import ( + "github.com/gnolang/gno/_test/net/http" +) + +type extendedRequest struct { + Request http.Request + + Data string +} + +func main() { + r := extendedRequest{} + // req := &r.Request + + println(r) + // XXX removed temporarily until recursion detection implemented for sprintString(). + // println(req) +} + +// Output: +// (struct{(struct{( string),( string),(0 int),(0 int),(nil github.com/gnolang/gno/_test/net/http.Header),(undefined),(0 int64),(nil []string),(false bool),( string),(nil github.com/gnolang/gno/_test/net/http.Values),(nil github.com/gnolang/gno/_test/net/http.Values),(nil github.com/gnolang/gno/_test/net/http.Header),( string),( string),(nil *github.com/gnolang/gno/_test/net/http.Response)} github.com/gnolang/gno/_test/net/http.Request),( string)} main.extendedRequest) diff --git a/gnovm/tests/files/types/shift_d4a.gno b/gnovm/tests/files/types/shift_d4a.gno new file mode 100644 index 00000000000..803da33ea64 --- /dev/null +++ b/gnovm/tests/files/types/shift_d4a.gno @@ -0,0 +1,9 @@ +package main + +func main() { + r := string(1<<2 == 1>>2) //special case with == !=, untyped bool + println(r) +} + +// Error: +// main/files/types/shift_d4a.gno:4:7: cannot convert BoolKind to StringKind diff --git a/gnovm/tests/files/types/shift_d5.gno b/gnovm/tests/files/types/shift_d5.gno new file mode 100644 index 00000000000..43c0e117f5e --- /dev/null +++ b/gnovm/tests/files/types/shift_d5.gno @@ -0,0 +1,10 @@ +package main + +func main() { + x := 11 + y := 1.0 << x // no const + println(y) +} + +// Error: +// main/files/types/shift_d5.gno:5:2: operator << not defined on: Float64Kind diff --git a/gnovm/tests/files/types/shift_d50.gno b/gnovm/tests/files/types/shift_d50.gno new file mode 100644 index 00000000000..fec552e48d7 --- /dev/null +++ b/gnovm/tests/files/types/shift_d50.gno @@ -0,0 +1,13 @@ +package main + +import "fmt" + +func main() { + x := 11 + y := uint64(-(1.0 << 2) << x) + println(y) + fmt.Printf("%T \n", y) +} + +// Error: +// main/files/types/shift_d50.gno:7:7: bigint underflows target kind diff --git a/gnovm/tests/files/types/shift_d51.gno b/gnovm/tests/files/types/shift_d51.gno new file mode 100644 index 00000000000..bd2b432479f --- /dev/null +++ b/gnovm/tests/files/types/shift_d51.gno @@ -0,0 +1,10 @@ +package main + +func main() { + a := 1.0 + a <<= 1 + println(a) +} + +// Error: +// main/files/types/shift_d51.gno:5:2: operator <<= not defined on: Float64Kind diff --git a/gnovm/tests/files/types/shift_d52.gno b/gnovm/tests/files/types/shift_d52.gno new file mode 100644 index 00000000000..f998381ef1c --- /dev/null +++ b/gnovm/tests/files/types/shift_d52.gno @@ -0,0 +1,10 @@ +package main + +func main() { + a := 1 + a <<= 1 + println(a) +} + +// Output: +// 2 diff --git a/gnovm/tests/files/types/shift_d53.gno b/gnovm/tests/files/types/shift_d53.gno new file mode 100644 index 00000000000..575dc1e146b --- /dev/null +++ b/gnovm/tests/files/types/shift_d53.gno @@ -0,0 +1,12 @@ +package main + +import "fmt" + +func main() { + a := 1 // a is inferred as int + b := a << 3 // b is also int + fmt.Printf("%T, %T, %d, %d \n", a, b, a, b) +} + +// Output: +// int, int, 1, 8 diff --git a/gnovm/tests/files/types/shift_d54.gno b/gnovm/tests/files/types/shift_d54.gno new file mode 100644 index 00000000000..13266f44379 --- /dev/null +++ b/gnovm/tests/files/types/shift_d54.gno @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + a := 5 // infer type int + var b int32 = 10 + c := b + a<<2 + + fmt.Printf("%T, %d \n", c, c) +} + +// Error: +// main/files/types/shift_d54.gno:8:7: invalid operation: mismatched types int32 and int diff --git a/gnovm/tests/files/types/shift_d55.gno b/gnovm/tests/files/types/shift_d55.gno new file mode 100644 index 00000000000..58628376421 --- /dev/null +++ b/gnovm/tests/files/types/shift_d55.gno @@ -0,0 +1,16 @@ +package main + +import "fmt" + +func shiftReturn() int64 { + return 1 << 4 // The shift result is cast to int64 +} + +func main() { + r := shiftReturn() + + fmt.Printf("%T, %d \n", r, r) +} + +// Output: +// int64, 16 diff --git a/gnovm/tests/files/types/shift_d56.gno b/gnovm/tests/files/types/shift_d56.gno new file mode 100644 index 00000000000..3f734bb993e --- /dev/null +++ b/gnovm/tests/files/types/shift_d56.gno @@ -0,0 +1,16 @@ +package main + +import "fmt" + +func shiftReturn() int64 { + return 1<<4 + int(1) // The shift result is cast to int64 +} + +func main() { + r := shiftReturn() + + fmt.Printf("%T, %d \n", r, r) +} + +// Error: +// main/files/types/shift_d56.gno:6:2: cannot use int as int64 diff --git a/gnovm/tests/files/types/shift_d5a.gno b/gnovm/tests/files/types/shift_d5a.gno new file mode 100644 index 00000000000..8490c751c88 --- /dev/null +++ b/gnovm/tests/files/types/shift_d5a.gno @@ -0,0 +1,10 @@ +package main + +func main() { + x := 11 + y := uint64(1.0 << x) + println(y) +} + +// Output: +// 2048 diff --git a/gnovm/tests/files/types/shift_d5b.gno b/gnovm/tests/files/types/shift_d5b.gno new file mode 100644 index 00000000000..8c04105a450 --- /dev/null +++ b/gnovm/tests/files/types/shift_d5b.gno @@ -0,0 +1,10 @@ +package main + +func main() { + x := 11 + y := float32(1.0 << x) + println(y) +} + +// Error: +// main/files/types/shift_d5b.gno:5:7: operator << not defined on: Float32Kind diff --git a/gnovm/tests/files/types/shift_d6.gno b/gnovm/tests/files/types/shift_d6.gno new file mode 100644 index 00000000000..1ebbf69e67b --- /dev/null +++ b/gnovm/tests/files/types/shift_d6.gno @@ -0,0 +1,18 @@ +package main + +import "fmt" + +func main() { + x := 11 + y := 1 << x + println(y) + fmt.Printf("%T \n", y) + fmt.Printf("%T \n", 1) + fmt.Printf("%T \n", x) +} + +// Output: +// 2048 +// int +// int +// int diff --git a/gnovm/tests/files/types/shift_d9.gno b/gnovm/tests/files/types/shift_d9.gno new file mode 100644 index 00000000000..e766e5e218d --- /dev/null +++ b/gnovm/tests/files/types/shift_d9.gno @@ -0,0 +1,9 @@ +package main + +func main() { + r := bool(1<<2+1 == 1>>2) + println(r) +} + +// Output: +// false diff --git a/gnovm/tests/files/types/shift_e0.gno b/gnovm/tests/files/types/shift_e0.gno new file mode 100644 index 00000000000..d5b75063d3e --- /dev/null +++ b/gnovm/tests/files/types/shift_e0.gno @@ -0,0 +1,8 @@ +package main + +func main() { + println(1 << -1) +} + +// Error: +// main/files/types/shift_e0.gno:4:10: invalid operation: negative shift count: (const (-1 bigint)) diff --git a/gnovm/tests/files/types/shift_e1.gno b/gnovm/tests/files/types/shift_e1.gno new file mode 100644 index 00000000000..343dee1f933 --- /dev/null +++ b/gnovm/tests/files/types/shift_e1.gno @@ -0,0 +1,8 @@ +package main + +func main() { + println(1.0 << float32(2.58485848)) +} + +// Error: +// main/files/types/shift_e1.gno:4:10: invalid operation: invalid shift count: (const (2.5848584 float32)) diff --git a/gnovm/tests/files/types/shift_e1a.gno b/gnovm/tests/files/types/shift_e1a.gno new file mode 100644 index 00000000000..bb6bedd2016 --- /dev/null +++ b/gnovm/tests/files/types/shift_e1a.gno @@ -0,0 +1,8 @@ +package main + +func main() { + println(1.0 << 2.0) +} + +// Output: +// 4 diff --git a/gnovm/tests/files/types/shift_e2.gno b/gnovm/tests/files/types/shift_e2.gno new file mode 100644 index 00000000000..192d5c1b3e9 --- /dev/null +++ b/gnovm/tests/files/types/shift_e2.gno @@ -0,0 +1,8 @@ +package main + +func main() { + println(1 << 1.25) +} + +// Error: +// main/files/types/shift_e2.gno:4:10: invalid operation: invalid shift count: (const (1.25 bigdec)) diff --git a/gnovm/tests/files/types/shift_e3.gno b/gnovm/tests/files/types/shift_e3.gno new file mode 100644 index 00000000000..81c803897c7 --- /dev/null +++ b/gnovm/tests/files/types/shift_e3.gno @@ -0,0 +1,9 @@ +package main + +func main() { + x := 1.25 + println(1 << x) +} + +// Error: +// main/files/types/shift_e3.gno:5:10: invalid operation: invalid shift count: x diff --git a/gnovm/tests/files/types/shift_e4.gno b/gnovm/tests/files/types/shift_e4.gno new file mode 100644 index 00000000000..02746eb04fe --- /dev/null +++ b/gnovm/tests/files/types/shift_e4.gno @@ -0,0 +1,9 @@ +package main + +func main() { + x := 1.25 + println(1 << x) +} + +// Error: +// main/files/types/shift_e4.gno:5:10: invalid operation: invalid shift count: x \ No newline at end of file diff --git a/gnovm/tests/files/types/shift_e5.gno b/gnovm/tests/files/types/shift_e5.gno new file mode 100644 index 00000000000..acd351bd50d --- /dev/null +++ b/gnovm/tests/files/types/shift_e5.gno @@ -0,0 +1,9 @@ +package main + +func main() { + x := -1 + println(1 << x) +} + +// Error: +// runtime error: negative shift amount: (-1 int) diff --git a/gnovm/tests/files/types/shift_e6.gno b/gnovm/tests/files/types/shift_e6.gno new file mode 100644 index 00000000000..43cb2464132 --- /dev/null +++ b/gnovm/tests/files/types/shift_e6.gno @@ -0,0 +1,9 @@ +package main + +func main() { + x := -1 + println(1 >> x) +} + +// Error: +// runtime error: negative shift amount: (-1 int) diff --git a/gnovm/tests/files/types/shift_e7.gno b/gnovm/tests/files/types/shift_e7.gno new file mode 100644 index 00000000000..c7d8aded350 --- /dev/null +++ b/gnovm/tests/files/types/shift_e7.gno @@ -0,0 +1,9 @@ +package main + +func main() { + y := 1 + y <<= -1 +} + +// Error: +// main/files/types/shift_e7.gno:5:2: invalid operation: negative shift count: (-1 bigint) diff --git a/gnovm/tests/files/types/shift_e7a.gno b/gnovm/tests/files/types/shift_e7a.gno new file mode 100644 index 00000000000..2e81fc102bc --- /dev/null +++ b/gnovm/tests/files/types/shift_e7a.gno @@ -0,0 +1,9 @@ +package main + +func main() { + a := float64(-100) + println(1 << a) +} + +// Error: +// main/files/types/shift_e7a.gno:5:10: invalid operation: invalid shift count: a diff --git a/gnovm/tests/files/types/shift_e7b.gno b/gnovm/tests/files/types/shift_e7b.gno new file mode 100644 index 00000000000..80766d2928e --- /dev/null +++ b/gnovm/tests/files/types/shift_e7b.gno @@ -0,0 +1,8 @@ +package main + +func main() { + println(1 << float64(-1)) +} + +// Error: +// main/files/types/shift_e7b.gno:4:10: invalid operation: invalid shift count: (const (-1 float64)) diff --git a/gnovm/tests/files/types/shift_e8.gno b/gnovm/tests/files/types/shift_e8.gno new file mode 100644 index 00000000000..1940dd9b8fb --- /dev/null +++ b/gnovm/tests/files/types/shift_e8.gno @@ -0,0 +1,9 @@ +package main + +func main() { + y := 1 + y <<= 1.25 +} + +// Error: +// main/files/types/shift_e8.gno:5:2: invalid operation: invalid shift count: (const (1.25 bigdec)) diff --git a/gnovm/tests/files/types/shift_e9.gno b/gnovm/tests/files/types/shift_e9.gno new file mode 100644 index 00000000000..2bd408860f2 --- /dev/null +++ b/gnovm/tests/files/types/shift_e9.gno @@ -0,0 +1,11 @@ +package main + +func main() { + x := -1 + y := 1 + y <<= x + println(y) +} + +// Error: +// runtime error: negative shift amount: (-1 int) diff --git a/gnovm/tests/files/types/shift_e9a.gno b/gnovm/tests/files/types/shift_e9a.gno new file mode 100644 index 00000000000..03ce9343948 --- /dev/null +++ b/gnovm/tests/files/types/shift_e9a.gno @@ -0,0 +1,11 @@ +package main + +func main() { + x := -1 + y := 1 + y >>= x + println(y) +} + +// Error: +// runtime error: negative shift amount: (-1 int) diff --git a/gnovm/tests/files/types/shift_f1a.gno b/gnovm/tests/files/types/shift_f1a.gno new file mode 100644 index 00000000000..ca35144bacc --- /dev/null +++ b/gnovm/tests/files/types/shift_f1a.gno @@ -0,0 +1,12 @@ +package main + +func main() { + var s uint = 33 + + var u1 bool + u1 = 1< bigint NEQ bigdec diff --git a/gnovm/tests/files/types/shift_f2e.gno b/gnovm/tests/files/types/shift_f2e.gno new file mode 100644 index 00000000000..dec0a2a6626 --- /dev/null +++ b/gnovm/tests/files/types/shift_f2e.gno @@ -0,0 +1,10 @@ +package main + +func main() { + var s uint = 33 + var u2 = 1.0<