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>
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)
ir.OMAKEMAP,
ir.OMAKESLICE,
ir.OMAKESLICECOPY,
+ ir.OMAX,
+ ir.OMIN,
ir.ONEW,
ir.OREAL,
ir.ORECOVERFP,
--- /dev/null
+// 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]()
+}