1
0
mirror of https://github.com/golang/go synced 2024-07-03 00:40:45 +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:
Cuong Manh Le 2021-11-01 02:04:13 +07:00
parent a59e33224e
commit a45457df82
4 changed files with 49 additions and 2 deletions

View File

@ -624,7 +624,7 @@ func (g *genInst) getDictOrSubdict(declInfo *instInfo, n ir.Node, nameNode *ir.N
// yet. If so, it imports the body.
func checkFetchBody(nameNode *ir.Name) {
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.
assert(nameNode.Func.Inl.Cost == 1 && nameNode.Sym().Pkg != types.LocalPkg)
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
// cached, then it calls genericSubst to create the new instantiation.
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
// number of instantiations we have to generate. You can actually have a mix

View 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()
}
}

View 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)() }

View 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