go/test/fixedbugs/issue50672.go
Cuong Manh Le 7b314d27ce cmd/compile: fix bad order of evaluation for multi-value f()(g()) calls
The compiler use to compile f()(g()) as:

	t1, t2 := g()
	f()(t1, t2)

That violates the Go spec, since when "..., all function calls, ... are
evaluated in lexical left-to-right order"

This PR fixes the bug by compiling f()(g()) as:

	t0 := f()
	t1, t2 := g()
	t0(t1, t2)

to make "f()" to be evaluated before "g()".

Fixes #50672

Change-Id: I6a766f3dfc7347d10f8fa3a151f6a5ea79bcf818
Reviewed-on: https://go-review.googlesource.com/c/go/+/392834
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2022-05-11 08:12:15 +00:00

106 lines
1.2 KiB
Go

// run
// Copyright 2022 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 main
var ok = false
func f() func(int, int) int {
ok = true
return func(int, int) int { return 0 }
}
func g() (int, int) {
if !ok {
panic("FAIL")
}
return 0, 0
}
var _ = f()(g())
func main() {
f1()
f2()
f3()
f4()
}
func f1() {
ok := false
f := func() func(int, int) {
ok = true
return func(int, int) {}
}
g := func() (int, int) {
if !ok {
panic("FAIL")
}
return 0, 0
}
f()(g())
}
type S struct{}
func (S) f(int, int) {}
func f2() {
ok := false
f := func() S {
ok = true
return S{}
}
g := func() (int, int) {
if !ok {
panic("FAIL")
}
return 0, 0
}
f().f(g())
}
func f3() {
ok := false
f := func() []func(int, int) {
ok = true
return []func(int, int){func(int, int) {}}
}
g := func() (int, int) {
if !ok {
panic("FAIL")
}
return 0, 0
}
f()[0](g())
}
type G[T any] struct{}
func (G[T]) f(int, int) {}
func f4() {
ok := false
f := func() G[int] {
ok = true
return G[int]{}
}
g := func() (int, int) {
if !ok {
panic("FAIL")
}
return 0, 0
}
f().f(g())
}