diff options
author | Cuong Manh Le <cuong.manhle.vn@gmail.com> | 2023-06-26 11:30:48 +0700 |
---|---|---|
committer | Gopher Robot <gobot@golang.org> | 2023-06-27 18:18:23 +0000 |
commit | 4ad4128d3c09e24f1e901635bd81ba2db7c46764 (patch) | |
tree | a039e8055e43b385d043c4dc08d324d867fffdd7 | |
parent | 4f36f7e4dd921be455810cc925ca122d71381156 (diff) | |
download | go-4ad4128d3c09e24f1e901635bd81ba2db7c46764.tar.gz go-4ad4128d3c09e24f1e901635bd81ba2db7c46764.zip |
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>
-rw-r--r-- | src/cmd/compile/internal/walk/order.go | 4 | ||||
-rw-r--r-- | test/fixedbugs/issue60990.go | 31 |
2 files changed, 34 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go index 1e76761de3..057e0b75b8 100644 --- a/src/cmd/compile/internal/walk/order.go +++ b/src/cmd/compile/internal/walk/order.go @@ -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 index 0000000000..ce94fa7197 --- /dev/null +++ b/test/fixedbugs/issue60990.go @@ -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]() +} |