From bd901af30bcc8b92c5ce708b5b7d6352b17b54e8 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Mon, 8 Aug 2022 12:40:49 -0700 Subject: [PATCH] cmd/compile/internal/ir: prevent NewClosureVar misuse 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 Run-TryBot: Matthew Dempsky Reviewed-by: Cuong Manh Le TryBot-Result: Gopher Robot --- src/cmd/compile/internal/ir/name.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/cmd/compile/internal/ir/name.go b/src/cmd/compile/internal/ir/name.go index 711d1dedc5..310481f6f0 100644 --- a/src/cmd/compile/internal/ir/name.go +++ b/src/cmd/compile/internal/ir/name.go @@ -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 -- 2.48.1