]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: fix bad order of evaluation for min/max builtin
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Mon, 26 Jun 2023 04:30:48 +0000 (11:30 +0700)
committerGopher Robot <gobot@golang.org>
Tue, 27 Jun 2023 18:18:23 +0000 (18:18 +0000)
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>
src/cmd/compile/internal/walk/order.go
test/fixedbugs/issue60990.go [new file with mode: 0644]

index 1e76761de3537918032c21b507ecf943c757f5c1..057e0b75b83ff63cf21e08bacd126b5e09951177 100644 (file)
@@ -755,7 +755,7 @@ func (o *orderState) stmt(n ir.Node) {
                o.out = append(o.out, n)
                o.popTemp(t)
 
-       case ir.OMAX, ir.OMIN, ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
+       case ir.OPRINT, ir.OPRINTN, ir.ORECOVERFP:
                n := n.(*ir.CallExpr)
                t := o.markTemp()
                o.call(n)
@@ -1247,6 +1247,8 @@ func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
                ir.OMAKEMAP,
                ir.OMAKESLICE,
                ir.OMAKESLICECOPY,
+               ir.OMAX,
+               ir.OMIN,
                ir.ONEW,
                ir.OREAL,
                ir.ORECOVERFP,
diff --git a/test/fixedbugs/issue60990.go b/test/fixedbugs/issue60990.go
new file mode 100644 (file)
index 0000000..ce94fa7
--- /dev/null
@@ -0,0 +1,31 @@
+// compile
+
+// Copyright 2023 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.
+
+package p
+
+type T struct{ _, _ []int }
+
+func F[_ int]() {
+       var f0, f1 float64
+       var b bool
+       _ = func(T, float64) bool {
+               b = deepEqual(0, 1)
+               return func() bool {
+                       f1 = min(f0, 0)
+                       return b
+               }()
+       }(T{nil, nil}, min(0, f1))
+       f0 = min(0, 1)
+}
+
+//go:noinline
+func deepEqual(x, y any) bool {
+       return x == y
+}
+
+func init() {
+       F[int]()
+}