Skip to content

Commit 4ad4128

Browse files
cuonglmgopherbot
authored andcommitted
cmd/compile: fix bad order of evaluation for min/max builtin
For float or string, min/max builtin performs a runtime call, so we need to save its result to temporary variable. Otherwise, the runtime call will clobber closure's arguments currently on the stack when passing min/max as argument to closures. Fixes #60990 Change-Id: I1397800f815ec7853182868678d0f760b22afff2 Reviewed-on: https://go-review.googlesource.com/c/go/+/506115 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Cherry Mui <cherryyz@google.com>
1 parent 4f36f7e commit 4ad4128

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ func (o *orderState) stmt(n ir.Node) {
755755
o.out = append(o.out, n)
756756
o.popTemp(t)
757757

758-
case ir.OMAX, ir.OMIN, ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
758+
case ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
759759
n := n.(*ir.CallExpr)
760760
t := o.markTemp()
761761
o.call(n)
@@ -1247,6 +1247,8 @@ func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
12471247
ir.OMAKEMAP,
12481248
ir.OMAKESLICE,
12491249
ir.OMAKESLICECOPY,
1250+
ir.OMAX,
1251+
ir.OMIN,
12501252
ir.ONEW,
12511253
ir.OREAL,
12521254
ir.ORECOVERFP,

test/fixedbugs/issue60990.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// compile
2+
3+
// Copyright 2023 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+
type T struct{ _, _ []int }
10+
11+
func F[_ int]() {
12+
var f0, f1 float64
13+
var b bool
14+
_ = func(T, float64) bool {
15+
b = deepEqual(0, 1)
16+
return func() bool {
17+
f1 = min(f0, 0)
18+
return b
19+
}()
20+
}(T{nil, nil}, min(0, f1))
21+
f0 = min(0, 1)
22+
}
23+
24+
//go:noinline
25+
func deepEqual(x, y any) bool {
26+
return x == y
27+
}
28+
29+
func init() {
30+
F[int]()
31+
}

0 commit comments

Comments
 (0)