From c32b3ecfb6d71a2c8d30333b90de543e5e0819da Mon Sep 17 00:00:00 2001 From: Kevin Chen Date: Fri, 19 Jul 2024 19:46:03 +0800 Subject: [PATCH] interp: fix mismatch assign statement panic Follow by the [Spec](https://go.dev/ref/spec#Assignment_statements): The number of operands on the left hand side must match the number of values. For instance, if f is a function returning two values `x, y = f()` assigns the first value to x and the second to y. In the second form, the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the nth expression on the right is assigned to the nth operand on the left. Fixes #1606 --- _test/assign19.go | 9 +++++++++ interp/cfg.go | 8 ++++++++ interp/interp_consistent_test.go | 1 + 3 files changed, 18 insertions(+) create mode 100644 _test/assign19.go diff --git a/_test/assign19.go b/_test/assign19.go new file mode 100644 index 000000000..497ee5058 --- /dev/null +++ b/_test/assign19.go @@ -0,0 +1,9 @@ +package main + +func main() { + a, b, c := 1, 2 + _, _, _ = a, b, c +} + +// Error: +// _test/assign19.go:4:2: cannot assign 2 values to 3 variables diff --git a/interp/cfg.go b/interp/cfg.go index 6da734d10..90db9a545 100644 --- a/interp/cfg.go +++ b/interp/cfg.go @@ -647,6 +647,14 @@ func (interp *Interpreter) cfg(root *node, sc *scope, importPath, pkgName string sbase = len(n.child) - n.nright } + // If len(RHS) > 1, each node must be single-valued, and the nth expression + // on the right is assigned to the nth operand on the left, so the number of + // nodes on the left and right sides must be equal + if n.nright > 1 && n.nright != n.nleft { + err = n.cfgErrorf("cannot assign %d values to %d variables", n.nright, n.nleft) + return + } + wireChild(n) for i := 0; i < n.nleft; i++ { dest, src := n.child[i], n.child[sbase+i] diff --git a/interp/interp_consistent_test.go b/interp/interp_consistent_test.go index 870997d7f..b8a8c55ca 100644 --- a/interp/interp_consistent_test.go +++ b/interp/interp_consistent_test.go @@ -45,6 +45,7 @@ func TestInterpConsistencyBuild(t *testing.T) { file.Name() == "assign11.go" || // expect error file.Name() == "assign12.go" || // expect error file.Name() == "assign15.go" || // expect error + file.Name() == "assign19.go" || // expect error file.Name() == "bad0.go" || // expect error file.Name() == "break0.go" || // expect error file.Name() == "cont3.go" || // expect error