mirror of
https://github.com/golang/go.git
synced 2024-09-21 18:38:37 +00:00
cmd/compile: make typecheck set n.Type.Nod when returning OTYPE
typecheck only set n.Type.Nod for declared type, and leave it nil for anonymous types, type alias. It leads to compiler crashes, because n.Type.Nod is nil at the time dowidth was called. Fixing it by set n.Type.Nod right after n.Type initialization if n.Op is OTYPE. When embedding interface cycles involve in type alias, it also helps pointing the error message to the position of the type alias declaration, instead of position of embedding interface. Fixes #31872 Change-Id: Ia18391e987036a91f42ba0c08b5506f52d07f683 Reviewed-on: https://go-review.googlesource.com/c/go/+/191540 Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
647dc1afc5
commit
e87fe0f1f5
@ -189,16 +189,7 @@ func dowidth(t *types.Type) {
|
||||
if t.Width == -2 {
|
||||
if !t.Broke() {
|
||||
t.SetBroke(true)
|
||||
// t.Nod should not be nil here, but in some cases is appears to be
|
||||
// (see issue #23823). For now (temporary work-around) at a minimum
|
||||
// don't crash and provide a meaningful error message.
|
||||
// TODO(gri) determine the correct fix during a regular devel cycle
|
||||
// (see issue #31872).
|
||||
if t.Nod == nil {
|
||||
yyerror("invalid recursive type %v", t)
|
||||
} else {
|
||||
yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t)
|
||||
}
|
||||
yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t)
|
||||
}
|
||||
|
||||
t.Width = 0
|
||||
|
@ -456,8 +456,7 @@ func typecheck1(n *Node, top int) (res *Node) {
|
||||
t = types.NewArray(r.Type, bound)
|
||||
}
|
||||
|
||||
n.Op = OTYPE
|
||||
n.Type = t
|
||||
setTypeNode(n, t)
|
||||
n.Left = nil
|
||||
n.Right = nil
|
||||
if !t.IsDDDArray() {
|
||||
@ -480,8 +479,8 @@ func typecheck1(n *Node, top int) (res *Node) {
|
||||
if r.Type.NotInHeap() {
|
||||
yyerror("go:notinheap map value not allowed")
|
||||
}
|
||||
n.Op = OTYPE
|
||||
n.Type = types.NewMap(l.Type, r.Type)
|
||||
|
||||
setTypeNode(n, types.NewMap(l.Type, r.Type))
|
||||
mapqueue = append(mapqueue, n) // check map keys when all types are settled
|
||||
n.Left = nil
|
||||
n.Right = nil
|
||||
@ -497,37 +496,28 @@ func typecheck1(n *Node, top int) (res *Node) {
|
||||
if l.Type.NotInHeap() {
|
||||
yyerror("chan of go:notinheap type not allowed")
|
||||
}
|
||||
t := types.NewChan(l.Type, n.TChanDir())
|
||||
n.Op = OTYPE
|
||||
n.Type = t
|
||||
|
||||
setTypeNode(n, types.NewChan(l.Type, n.TChanDir()))
|
||||
n.Left = nil
|
||||
n.ResetAux()
|
||||
|
||||
case OTSTRUCT:
|
||||
ok |= Etype
|
||||
n.Op = OTYPE
|
||||
n.Type = tostruct(n.List.Slice())
|
||||
if n.Type == nil || n.Type.Broke() {
|
||||
t := tostruct(n.List.Slice())
|
||||
if t.Broke() {
|
||||
n.Type = nil
|
||||
return n
|
||||
}
|
||||
setTypeNode(n, t)
|
||||
n.List.Set(nil)
|
||||
|
||||
case OTINTER:
|
||||
ok |= Etype
|
||||
n.Op = OTYPE
|
||||
n.Type = tointerface(n.List.Slice())
|
||||
if n.Type == nil {
|
||||
return n
|
||||
}
|
||||
setTypeNode(n, tointerface(n.List.Slice()))
|
||||
|
||||
case OTFUNC:
|
||||
ok |= Etype
|
||||
n.Op = OTYPE
|
||||
n.Type = functype(n.Left, n.List.Slice(), n.Rlist.Slice())
|
||||
if n.Type == nil {
|
||||
return n
|
||||
}
|
||||
setTypeNode(n, functype(n.Left, n.List.Slice(), n.Rlist.Slice()))
|
||||
n.Left = nil
|
||||
n.List.Set(nil)
|
||||
n.Rlist.Set(nil)
|
||||
@ -543,8 +533,7 @@ func typecheck1(n *Node, top int) (res *Node) {
|
||||
}
|
||||
if l.Op == OTYPE {
|
||||
ok |= Etype
|
||||
n.Op = OTYPE
|
||||
n.Type = types.NewPtr(l.Type)
|
||||
setTypeNode(n, types.NewPtr(l.Type))
|
||||
// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
|
||||
// Don't checkwidth [...] arrays, though, since they
|
||||
// will be replaced by concrete-sized arrays. Issue 20333.
|
||||
@ -3683,8 +3672,7 @@ func typecheckdef(n *Node) {
|
||||
defercheckwidth()
|
||||
}
|
||||
n.SetWalkdef(1)
|
||||
n.Type = types.New(TFORW)
|
||||
n.Type.Nod = asTypesNode(n)
|
||||
setTypeNode(n, types.New(TFORW))
|
||||
n.Type.Sym = n.Sym // TODO(gri) this also happens in typecheckdeftype(n) - where should it happen?
|
||||
nerrors0 := nerrors
|
||||
typecheckdeftype(n)
|
||||
@ -3951,3 +3939,10 @@ func deadcodeexpr(n *Node) *Node {
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// setTypeNode sets n to an OTYPE node representing t.
|
||||
func setTypeNode(n *Node, t *types.Type) {
|
||||
n.Op = OTYPE
|
||||
n.Type = t
|
||||
n.Type.Nod = asTypesNode(n)
|
||||
}
|
||||
|
@ -6,10 +6,10 @@
|
||||
|
||||
package p
|
||||
|
||||
type I1 = interface {
|
||||
type I1 = interface { // ERROR "invalid recursive type"
|
||||
I2
|
||||
}
|
||||
|
||||
type I2 interface { // ERROR "invalid recursive type"
|
||||
type I2 interface {
|
||||
I1
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user