From 4ad4128d3c09e24f1e901635bd81ba2db7c46764 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Mon, 26 Jun 2023 11:30:48 +0700 Subject: [PATCH] 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 Reviewed-by: Matthew Dempsky Run-TryBot: Cuong Manh Le Auto-Submit: Cuong Manh Le Reviewed-by: Cherry Mui --- src/cmd/compile/internal/walk/order.go | 4 +++- test/fixedbugs/issue60990.go | 31 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue60990.go 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]() +} -- 2.48.1