mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
cmd/compile: fix handling of ir.CurFunc during stenciling
The transform functions (specifically transformArgs, which is used from transformCall/transformReturn) require that ir.CurFunc is set correctly. Since transformCall() is used on the call of an instantiated generic function, we need to set ir.CurFunc correctly in stencil(). Also, correctly save/restore ir.CurFunc in genericSubst(). Without this fix, ir.CurFunc can be nil when we call TransformCall() from stencil(), which leads to some temp variables being added incorrectly to ir.TodoFunc (which leads to the fatal panic in the issue). Fixes #45722 Change-Id: Iddf4a67d28f2100dde8cde5dbc9ca1e00dad6089 Reviewed-on: https://go-review.googlesource.com/c/go/+/313869 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com>
This commit is contained in:
parent
d553c0144d
commit
55c517a8b3
|
@ -52,6 +52,8 @@ func (g *irgen) stencil() {
|
|||
// Skip any generic functions
|
||||
continue
|
||||
}
|
||||
// transformCall() below depends on CurFunc being set.
|
||||
ir.CurFunc = decl.(*ir.Func)
|
||||
|
||||
case ir.OAS, ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2FUNC, ir.OAS2MAPR, ir.OAS2RECV, ir.OASOP:
|
||||
// These are all the various kinds of global assignments,
|
||||
|
@ -127,6 +129,7 @@ func (g *irgen) stencil() {
|
|||
if base.Flag.W > 1 && modified {
|
||||
ir.Dump(fmt.Sprintf("\nmodified %v", decl), decl)
|
||||
}
|
||||
ir.CurFunc = nil
|
||||
// We may have seen new fully-instantiated generic types while
|
||||
// instantiating any needed functions/methods in the above
|
||||
// function. If so, instantiate all the methods of those types
|
||||
|
@ -275,6 +278,9 @@ func (g *irgen) genericSubst(newsym *types.Sym, nameNode *ir.Name, targs []ir.No
|
|||
newf.Nname.Func = newf
|
||||
newf.Nname.Defn = newf
|
||||
newsym.Def = newf.Nname
|
||||
savef := ir.CurFunc
|
||||
// transformCall/transformReturn (called during stenciling of the body)
|
||||
// depend on ir.CurFunc being set.
|
||||
ir.CurFunc = newf
|
||||
|
||||
assert(len(tparams) == len(targs))
|
||||
|
@ -310,7 +316,7 @@ func (g *irgen) genericSubst(newsym *types.Sym, nameNode *ir.Name, targs []ir.No
|
|||
|
||||
// Make sure name/type of newf is set before substituting the body.
|
||||
newf.Body = subst.list(gf.Body)
|
||||
ir.CurFunc = nil
|
||||
ir.CurFunc = savef
|
||||
|
||||
return newf
|
||||
}
|
||||
|
|
34
test/typeparam/issue45722.go
Normal file
34
test/typeparam/issue45722.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
// run -gcflags=-G=3
|
||||
|
||||
// Copyright 2021 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
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
func try[T any](v T, err error) T {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func handle(handle func(error)) {
|
||||
if issue := recover(); issue != nil {
|
||||
if e, ok := issue.(error); ok && e != nil {
|
||||
handle(e)
|
||||
} else {
|
||||
handle(fmt.Errorf("%v", e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer handle(func(e error) { log.Fatalln(e) })
|
||||
_ = try(fmt.Print(""))
|
||||
}
|
Loading…
Reference in a new issue