]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/ir: prevent NewClosureVar misuse
authorMatthew Dempsky <mdempsky@google.com>
Mon, 8 Aug 2022 19:40:49 +0000 (12:40 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 9 Aug 2022 16:41:24 +0000 (16:41 +0000)
NewClosureVar should only be called to capture locally declared
variables in the enclosing function scope. This CL adds a check to
make sure it's used that way, in particular to make sure it's not
called to capture global variables.

This came up because for generic method values, we desugar the method
value into a function literal that captures the receiver value after
evaluating it. However, due to compiler backend limitations, for
package-scope generic method values we spill the receiver value into a
global variable rather than capturing it normally.

To prevent confusing backend issues when misusing NewClosureVar with
global variables, this CL adds an extra check.

Change-Id: I80f0f083dc80f70c7f0298020efe56dba00b67d7
Reviewed-on: https://go-review.googlesource.com/c/go/+/422195
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/ir/name.go

index 711d1dedc56ec1819e954cc4bbb9fbc9ab7e0dfd..310481f6f0579e1810bfc9ae15f637aac75f38f6 100644 (file)
@@ -336,6 +336,14 @@ func (n *Name) Byval() bool {
 // NewClosureVar returns a new closure variable for fn to refer to
 // outer variable n.
 func NewClosureVar(pos src.XPos, fn *Func, n *Name) *Name {
+       switch n.Class {
+       case PAUTO, PPARAM, PPARAMOUT, PAUTOHEAP:
+               // ok
+       default:
+               // Prevent mistaken capture of global variables.
+               base.Fatalf("NewClosureVar: %+v", n)
+       }
+
        c := NewNameAt(pos, n.Sym())
        c.Curfn = fn
        c.Class = PAUTOHEAP