cmd/compile: in append(f()), type convert appended items

The second and subsequent return values from f() need to be
converted to the element type of the first return value from f()
(which must be a slice).

Fixes #22327

Change-Id: I5c0a424812c82c1b95b6d124c5626cfc4408bdb6
Reviewed-on: https://go-review.googlesource.com/c/142718
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Keith Randall 2018-10-16 14:31:49 -07:00 committed by Keith Randall
parent 86ce1cb060
commit dca769dca9
2 changed files with 26 additions and 3 deletions

View file

@ -2884,6 +2884,8 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
}
walkexprlistsafe(n.List.Slice()[1:], init)
nsrc := n.List.First()
// walkexprlistsafe will leave OINDEX (s[n]) alone if both s
// and n are name or literal, but those may index the slice we're
// modifying here. Fix explicitly.
@ -2892,11 +2894,14 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
// before we begin to modify the slice in a visible way.
ls := n.List.Slice()[1:]
for i, n := range ls {
ls[i] = cheapexpr(n, init)
n = cheapexpr(n, init)
if !eqtype(n.Type, nsrc.Type.Elem()) {
n = assignconv(n, nsrc.Type.Elem(), "append")
n = walkexpr(n, init)
}
ls[i] = n
}
nsrc := n.List.First()
argc := n.List.Len() - 1
if argc < 1 {
return nsrc

View file

@ -0,0 +1,18 @@
// compile
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Using a multi-result function as an argument to
// append should compile successfully. Previously there
// was a missing *int -> interface{} conversion that caused
// the compiler to ICE.
package p
func f() ([]interface{}, *int) {
return nil, nil
}
var _ = append(f())