]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/inline: fix bug in param flags heuristics
authorThan McIntosh <thanm@google.com>
Mon, 30 Oct 2023 16:55:42 +0000 (12:55 -0400)
committerThan McIntosh <thanm@google.com>
Tue, 21 Nov 2023 17:27:50 +0000 (17:27 +0000)
Fix a bug in the code that analyzes how function parameters are used,
which wasn't properly handling certain types of closures. The code
in question has support for deriving flags for a given parameter based
on whether it is passed to a call. Example:

    func foo(f1 func(int)) {
       bar(32, f1)
    }
    func bar(x int, f2 func()) {
       f2(x)
    }

When analyzing "bar", we can derive the "FeedsIndirectCall" flag for
parameter "f1" by virtue of the fact that it is passed directly to
"bar", and bar's corresponding parameter "f2" has the flag set. For
a more complex example such as

    func foo(f1 func(int)) func() int {
       return func(q int) int {            <<-- HERE
         bar(99, f1)
 return q
       }
    }
    func bar(x int, f2 func()) {
       f2(x)
    }

The heuristics code would panic when examining the closure marked above
due to the fact that the call to "bar" was passing an ir.Name with class
PPARAM, but no such param was present in the enclosing function.

Change-Id: I30436ce716b51bfb03e42e7abe76a4514e6b9285
Reviewed-on: https://go-review.googlesource.com/c/go/+/539320
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/inline/inlheur/analyze_func_params.go

index 5e61485532a0ec7b61110296915d7bcb06d36ecd..d85d73b2efc487a94a78c56589ff91dcfa2fd659 100644 (file)
@@ -249,7 +249,13 @@ func (pa *paramsAnalyzer) deriveFlagsFromCallee(ce *ir.CallExpr, callee *ir.Func
                        return
                }
                callerParamIdx := pa.findParamIdx(name)
-               if callerParamIdx == -1 || pa.params[callerParamIdx] == nil {
+               // note that callerParamIdx may return -1 in the case where
+               // the param belongs not to the current closure func we're
+               // analyzing but to an outer enclosing func.
+               if callerParamIdx == -1 {
+                       return
+               }
+               if pa.params[callerParamIdx] == nil {
                        panic("something went wrong")
                }
                if !pa.top[callerParamIdx] &&