mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile: fix panic when refer to method of imported instantiated type
In case of reference to method call of an imported fully-instantiated type, nameNode.Func will be nil causes checkFetchBody panic. To fix this, make sure checkFetchBody is only called when Func is not nil. Fixes #49246 Change-Id: I32e9208385a86d4600d8ebf6f5efd8fca571ea16 Reviewed-on: https://go-review.googlesource.com/c/go/+/360056 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Trust: Dan Scales <danscales@google.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
a59e33224e
commit
a45457df82
@ -624,7 +624,7 @@ func (g *genInst) getDictOrSubdict(declInfo *instInfo, n ir.Node, nameNode *ir.N
|
|||||||
// yet. If so, it imports the body.
|
// yet. If so, it imports the body.
|
||||||
func checkFetchBody(nameNode *ir.Name) {
|
func checkFetchBody(nameNode *ir.Name) {
|
||||||
if nameNode.Func.Body == nil && nameNode.Func.Inl != nil {
|
if nameNode.Func.Body == nil && nameNode.Func.Inl != nil {
|
||||||
// If there is no body yet but Func.Inl exists, then we can can
|
// If there is no body yet but Func.Inl exists, then we can
|
||||||
// import the whole generic body.
|
// import the whole generic body.
|
||||||
assert(nameNode.Func.Inl.Cost == 1 && nameNode.Sym().Pkg != types.LocalPkg)
|
assert(nameNode.Func.Inl.Cost == 1 && nameNode.Sym().Pkg != types.LocalPkg)
|
||||||
typecheck.ImportBody(nameNode.Func)
|
typecheck.ImportBody(nameNode.Func)
|
||||||
@ -638,7 +638,18 @@ func checkFetchBody(nameNode *ir.Name) {
|
|||||||
// with the type arguments shapes. If the instantiated function is not already
|
// with the type arguments shapes. If the instantiated function is not already
|
||||||
// cached, then it calls genericSubst to create the new instantiation.
|
// cached, then it calls genericSubst to create the new instantiation.
|
||||||
func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMeth bool) *instInfo {
|
func (g *genInst) getInstantiation(nameNode *ir.Name, shapes []*types.Type, isMeth bool) *instInfo {
|
||||||
checkFetchBody(nameNode)
|
if nameNode.Func == nil {
|
||||||
|
// If nameNode.Func is nil, this must be a reference to a method of
|
||||||
|
// an imported instantiated type. We will have already called
|
||||||
|
// g.instantiateMethods() on the fully-instantiated type, so
|
||||||
|
// g.instInfoMap[sym] will be non-nil below.
|
||||||
|
rcvr := nameNode.Type().Recv()
|
||||||
|
if rcvr == nil || !deref(rcvr.Type).IsFullyInstantiated() {
|
||||||
|
base.FatalfAt(nameNode.Pos(), "Unexpected function instantiation %v with no body", nameNode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
checkFetchBody(nameNode)
|
||||||
|
}
|
||||||
|
|
||||||
// Convert any non-shape type arguments to their shape, so we can reduce the
|
// Convert any non-shape type arguments to their shape, so we can reduce the
|
||||||
// number of instantiations we have to generate. You can actually have a mix
|
// number of instantiations we have to generate. You can actually have a mix
|
||||||
|
20
test/typeparam/issue49246.dir/a.go
Normal file
20
test/typeparam/issue49246.dir/a.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// 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 a
|
||||||
|
|
||||||
|
type R[T any] struct{ v T }
|
||||||
|
|
||||||
|
func (r R[T]) Self() R[T] { return R[T]{} }
|
||||||
|
|
||||||
|
type Fn[T any] func() R[T]
|
||||||
|
|
||||||
|
func X() (r R[int]) { return r.Self() }
|
||||||
|
|
||||||
|
func Y[T any](a Fn[T]) Fn[int] {
|
||||||
|
return func() (r R[int]) {
|
||||||
|
// No crash: return R[int]{}
|
||||||
|
return r.Self()
|
||||||
|
}
|
||||||
|
}
|
9
test/typeparam/issue49246.dir/b.go
Normal file
9
test/typeparam/issue49246.dir/b.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// 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 b
|
||||||
|
|
||||||
|
import "./a"
|
||||||
|
|
||||||
|
func Crash() { a.Y(a.X)() }
|
7
test/typeparam/issue49246.go
Normal file
7
test/typeparam/issue49246.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// compiledir -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 ignored
|
Loading…
x
Reference in New Issue
Block a user