From db955e671f59071c810aa3485cfae13e8fad9f3c Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Tue, 15 Jun 2021 14:34:08 +0200 Subject: [PATCH] interp: fix append a slice on binary slice Fixes #1128. --- _test/append3.go | 14 ++++++++++++++ _test/issue-1128.go | 10 ++++++++++ interp/run.go | 12 ++++++------ interp/type.go | 7 +++++++ 4 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 _test/append3.go create mode 100644 _test/issue-1128.go diff --git a/_test/append3.go b/_test/append3.go new file mode 100644 index 00000000..a539cbfd --- /dev/null +++ b/_test/append3.go @@ -0,0 +1,14 @@ +package main + +import "fmt" + +func main() { + a := []int{1, 2} + b := [2]int{3, 4} + fmt.Println(append(a, b[:]...)) + fmt.Println(append(a, []int{5, 6}...)) +} + +// Output: +// [1 2 3 4] +// [1 2 5 6] diff --git a/_test/issue-1128.go b/_test/issue-1128.go new file mode 100644 index 00000000..cc1098b8 --- /dev/null +++ b/_test/issue-1128.go @@ -0,0 +1,10 @@ +package main + +import "net" + +func main() { + c := append(net.Buffers{}, []byte{}) + println(len(c)) +} + +// Output: 1 diff --git a/interp/run.go b/interp/run.go index 205b2ea7..4632d46a 100644 --- a/interp/run.go +++ b/interp/run.go @@ -2917,7 +2917,7 @@ func _append(n *node) { if len(n.child) == 3 { c1, c2 := n.child[1], n.child[2] if (c1.typ.cat == valueT || c2.typ.cat == valueT) && c1.typ.rtype == c2.typ.rtype || - (c2.typ.cat == arrayT || c2.typ.cat == sliceT || c2.typ.cat == variadicT) && c2.typ.val.id() == n.typ.val.id() || + isArray(c2.typ) && c2.typ.elem().id() == n.typ.elem().id() || isByteArray(c1.typ.TypeOf()) && isString(c2.typ.TypeOf()) { appendSlice(n) return @@ -2957,13 +2957,13 @@ func _append(n *node) { } } else { var value0 func(*frame) reflect.Value - switch { - case isEmptyInterface(n.typ.val): + switch elem := n.typ.elem(); { + case isEmptyInterface(elem): value0 = genValue(n.child[2]) - case isInterfaceSrc(n.typ.val): + case isInterfaceSrc(elem): value0 = genValueInterface(n.child[2]) - case isRecursiveType(n.typ.val, n.typ.val.rtype): - value0 = genValueRecursiveInterface(n.child[2], n.typ.val.rtype) + case isRecursiveType(elem, elem.rtype): + value0 = genValueRecursiveInterface(n.child[2], elem.rtype) case n.child[2].typ.untyped: value0 = genValueAs(n.child[2], n.child[1].typ.TypeOf().Elem()) default: diff --git a/interp/type.go b/interp/type.go index 7fb6792c..238062a6 100644 --- a/interp/type.go +++ b/interp/type.go @@ -1601,6 +1601,13 @@ func (t *itype) hasNil() bool { return false } +func (t *itype) elem() *itype { + if t.cat == valueT { + return &itype{cat: valueT, rtype: t.rtype.Elem()} + } + return t.val +} + func copyDefined(m map[string]*itype) map[string]*itype { n := make(map[string]*itype, len(m)) for k, v := range m {