Skip to content

Commit c4f87ed

Browse files
committed
cmd/compile: fix "append outside assignment" ICE
Some special-case code paths in order.go didn't expect OCALLFUNC to have Ninit; in particular, OAS2FUNC and ODEFER/OGO failed to call o.init on their child OCALLFUNC node. This resulted in not all of the AST being properly ordered. This was noticed because order is responsible for introducing an invariant around how OAPPEND is used, which is enforced by walk. However, there were perhaps simpler cases (e.g., simple order of evaluation) that were being silently miscompiled. Fixes #31010. Change-Id: Ib928890ab5ec2aebd8e30a030bc2b404387f9123 Reviewed-on: https://go-review.googlesource.com/c/go/+/169257 Run-TryBot: Matthew Dempsky <[email protected]> Reviewed-by: Josh Bleecher Snyder <[email protected]>
1 parent 270de1c commit c4f87ed

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

src/cmd/compile/internal/gc/order.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,10 @@ func (o *Order) init(n *Node) {
383383
// call orders the call expression n.
384384
// n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
385385
func (o *Order) call(n *Node) {
386+
if n.Ninit.Len() > 0 {
387+
// Caller should have already called o.init(n).
388+
Fatalf("%v with unexpected ninit", n.Op)
389+
}
386390
n.Left = o.expr(n.Left, nil)
387391
n.Right = o.expr(n.Right, nil) // ODDDARG temp
388392
o.exprList(n.List)
@@ -578,6 +582,7 @@ func (o *Order) stmt(n *Node) {
578582
case OAS2FUNC:
579583
t := o.markTemp()
580584
o.exprList(n.List)
585+
o.init(n.Rlist.First())
581586
o.call(n.Rlist.First())
582587
o.as2(n)
583588
o.cleanTemp(t)
@@ -637,6 +642,7 @@ func (o *Order) stmt(n *Node) {
637642
// Special: order arguments to inner call but not call itself.
638643
case ODEFER, OGO:
639644
t := o.markTemp()
645+
o.init(n.Left)
640646
o.call(n.Left)
641647
o.out = append(o.out, n)
642648
o.cleanTemp(t)

test/fixedbugs/issue31010.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// compile
2+
3+
// Copyright 2019 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package p
8+
9+
var (
10+
x int
11+
xs []int
12+
)
13+
14+
func a([]int) (int, error)
15+
16+
func b() (int, error) {
17+
return a(append(xs, x))
18+
}
19+
20+
func c(int, error) (int, error)
21+
22+
func d() (int, error) {
23+
return c(b())
24+
}

0 commit comments

Comments
 (0)