]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: fix -m=2 output for recursive function with closures
authorKeith Randall <khr@golang.org>
Fri, 27 Jan 2023 23:43:52 +0000 (15:43 -0800)
committerKeith Randall <khr@google.com>
Sat, 28 Jan 2023 04:29:02 +0000 (04:29 +0000)
ir.VisitFuncsBottomUp returns recursive==true for functions which
call themselves. It also returns any closures inside that function.
We don't want to report the closures as recursive, as they really
aren't. Only the containing function is recursive.

Fixes #54159

Change-Id: I3b4d6710a389ec1d6b250ba8a7065f2e985bdbe1
Reviewed-on: https://go-review.googlesource.com/c/go/+/463233
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: Keith Randall <khr@golang.org>

src/cmd/compile/internal/inline/inl.go
test/fixedbugs/issue54159.go [new file with mode: 0644]

index 781dae1396b206e71db037f4a9a6d34df2531961..5b855252c01580014fb749075ec8a56c8e402cb9 100644 (file)
@@ -195,7 +195,7 @@ func InlineDecls(p *pgo.Profile, decls []ir.Node, doInline bool) {
                                // across more than one function.
                                CanInline(n, p)
                        } else {
-                               if base.Flag.LowerM > 1 {
+                               if base.Flag.LowerM > 1 && n.OClosure == nil {
                                        fmt.Printf("%v: cannot inline %v: recursive\n", ir.Line(n), n.Nname)
                                }
                        }
diff --git a/test/fixedbugs/issue54159.go b/test/fixedbugs/issue54159.go
new file mode 100644 (file)
index 0000000..8ef0e68
--- /dev/null
@@ -0,0 +1,22 @@
+// errorcheck -0 -m=2
+
+// 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 main
+
+func run() { // ERROR "cannot inline run: recursive"
+       f := func() { // ERROR "can inline run.func1 with cost .* as:.*" "func literal does not escape"
+               g() // ERROR "inlining call to g"
+       }
+       f() // ERROR "inlining call to run.func1" "inlining call to g"
+       run()
+}
+
+func g() { // ERROR "can inline g with cost .* as:.*"
+}
+
+func main() { // ERROR "can inline main with cost .* as:.*"
+       run()
+}