1
0
mirror of https://github.com/golang/go synced 2024-11-26 17:46:57 -07:00

cmd/compile/internal/inline: fix bug in param flags heuristics

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>
This commit is contained in:
Than McIntosh 2023-10-30 12:55:42 -04:00
parent 0cb45bac01
commit 3255fca993

View File

@ -249,7 +249,13 @@ func (pa *paramsAnalyzer) deriveFlagsFromCallee(ce *ir.CallExpr, callee *ir.Func
return return
} }
callerParamIdx := pa.findParamIdx(name) 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") panic("something went wrong")
} }
if !pa.top[callerParamIdx] && if !pa.top[callerParamIdx] &&