From af92e81ec2eaf7e1d19eb59911f12d64e9a1e72f Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Wed, 17 Apr 2024 19:27:57 +0200 Subject: [PATCH 1/3] fix(gnovm): fix check for ASSIGN_SHL/SHR in preprocessor --- gnovm/pkg/gnolang/preprocess.go | 14 +++++++------- gnovm/tests/files/assign22.gno | 12 ++++++++++++ 2 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 gnovm/tests/files/assign22.gno diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 33a6beea581..4ff9d9fa4a6 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -1609,7 +1609,13 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { } } else { // ASSIGN. // NOTE: Keep in sync with DEFINE above. - if len(n.Lhs) > len(n.Rhs) { + if n.Op == SHL_ASSIGN || n.Op == SHR_ASSIGN { + if len(n.Lhs) != 1 || len(n.Rhs) != 1 { + panic("should not happen") + } + // Special case if shift assign <<= or >>=. + checkOrConvertType(store, last, &n.Rhs[0], UintType, false) + } else if len(n.Lhs) > len(n.Rhs) { // TODO dry code w/ above. // Unpack n.Rhs[0] to n.Lhs[:] if len(n.Rhs) != 1 { @@ -1641,12 +1647,6 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { default: panic("should not happen") } - } else if n.Op == SHL_ASSIGN || n.Op == SHR_ASSIGN { - if len(n.Lhs) != 1 || len(n.Rhs) != 1 { - panic("should not happen") - } - // Special case if shift assign <<= or >>=. - checkOrConvertType(store, last, &n.Rhs[0], UintType, false) } else { // General case: a, b = x, y. for i, lx := range n.Lhs { diff --git a/gnovm/tests/files/assign22.gno b/gnovm/tests/files/assign22.gno new file mode 100644 index 00000000000..3a49d9f57fe --- /dev/null +++ b/gnovm/tests/files/assign22.gno @@ -0,0 +1,12 @@ +package main + +func main() { + m := map[string]int{"a": 1} + var s int + var ok bool + s, ok <<= m["a"] + println(s, ok) +} + +// Error: +// main/files/assign22.gno:7: should not happen From 40edbfbd61b016ea5525d11b7117e5ca74c655f0 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Thu, 18 Apr 2024 18:23:45 +0200 Subject: [PATCH 2/3] amend "should not happen" error message --- gnovm/pkg/gnolang/preprocess.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 4ff9d9fa4a6..59d24a5cd01 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -1611,7 +1611,7 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { // NOTE: Keep in sync with DEFINE above. if n.Op == SHL_ASSIGN || n.Op == SHR_ASSIGN { if len(n.Lhs) != 1 || len(n.Rhs) != 1 { - panic("should not happen") + panic("operators <<= and >>= require one expression on lhs and rhs") } // Special case if shift assign <<= or >>=. checkOrConvertType(store, last, &n.Rhs[0], UintType, false) From fd022c68fbff69507dd1c39a20b9edcc283e9169 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Thu, 18 Apr 2024 19:57:01 +0200 Subject: [PATCH 3/3] perform same check for all assignment operators --- gnovm/pkg/gnolang/preprocess.go | 13 +++++++++---- gnovm/tests/files/assign22.gno | 2 +- gnovm/tests/files/assign23.gno | 12 ++++++++++++ 3 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 gnovm/tests/files/assign23.gno diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 59d24a5cd01..c485fd43346 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -1607,12 +1607,17 @@ func Preprocess(store Store, ctx BlockNode, n Node) Node { } } } - } else { // ASSIGN. + } else { // ASSIGN, or assignment operation (+=, -=, <<=, etc.) + // If this is an assignment operation, ensure there's only 1 + // expr on lhs/rhs. + if n.Op != ASSIGN && + (len(n.Lhs) != 1 || len(n.Rhs) != 1) { + panic("assignment operator " + n.Op.TokenString() + + " requires only one expression on lhs and rhs") + } + // NOTE: Keep in sync with DEFINE above. if n.Op == SHL_ASSIGN || n.Op == SHR_ASSIGN { - if len(n.Lhs) != 1 || len(n.Rhs) != 1 { - panic("operators <<= and >>= require one expression on lhs and rhs") - } // Special case if shift assign <<= or >>=. checkOrConvertType(store, last, &n.Rhs[0], UintType, false) } else if len(n.Lhs) > len(n.Rhs) { diff --git a/gnovm/tests/files/assign22.gno b/gnovm/tests/files/assign22.gno index 3a49d9f57fe..bedb8b4adb8 100644 --- a/gnovm/tests/files/assign22.gno +++ b/gnovm/tests/files/assign22.gno @@ -9,4 +9,4 @@ func main() { } // Error: -// main/files/assign22.gno:7: should not happen +// main/files/assign22.gno:7: assignment operator <<= requires only one expression on lhs and rhs diff --git a/gnovm/tests/files/assign23.gno b/gnovm/tests/files/assign23.gno new file mode 100644 index 00000000000..ab648774028 --- /dev/null +++ b/gnovm/tests/files/assign23.gno @@ -0,0 +1,12 @@ +package main + +func main() { + m := map[string]int{"a": 1} + var s int + var ok bool + s, ok += m["a"] + println(s, ok) +} + +// Error: +// main/files/assign23.gno:7: assignment operator += requires only one expression on lhs and rhs