Skip to content

Commit 9e3a158

Browse files
cuonglmtomocy
authored andcommitted
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 golang#31872 Change-Id: Ia18391e987036a91f42ba0c08b5506f52d07f683 Reviewed-on: https://go-review.googlesource.com/c/go/+/191540 Run-TryBot: Cuong Manh Le <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 2f0016c commit 9e3a158

File tree

3 files changed

+22
-36
lines changed

3 files changed

+22
-36
lines changed

src/cmd/compile/internal/gc/align.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -189,16 +189,7 @@ func dowidth(t *types.Type) {
189189
if t.Width == -2 {
190190
if !t.Broke() {
191191
t.SetBroke(true)
192-
// t.Nod should not be nil here, but in some cases is appears to be
193-
// (see issue #23823). For now (temporary work-around) at a minimum
194-
// don't crash and provide a meaningful error message.
195-
// TODO(gri) determine the correct fix during a regular devel cycle
196-
// (see issue #31872).
197-
if t.Nod == nil {
198-
yyerror("invalid recursive type %v", t)
199-
} else {
200-
yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t)
201-
}
192+
yyerrorl(asNode(t.Nod).Pos, "invalid recursive type %v", t)
202193
}
203194

204195
t.Width = 0

src/cmd/compile/internal/gc/typecheck.go

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -456,8 +456,7 @@ func typecheck1(n *Node, top int) (res *Node) {
456456
t = types.NewArray(r.Type, bound)
457457
}
458458

459-
n.Op = OTYPE
460-
n.Type = t
459+
setTypeNode(n, t)
461460
n.Left = nil
462461
n.Right = nil
463462
if !t.IsDDDArray() {
@@ -480,8 +479,8 @@ func typecheck1(n *Node, top int) (res *Node) {
480479
if r.Type.NotInHeap() {
481480
yyerror("go:notinheap map value not allowed")
482481
}
483-
n.Op = OTYPE
484-
n.Type = types.NewMap(l.Type, r.Type)
482+
483+
setTypeNode(n, types.NewMap(l.Type, r.Type))
485484
mapqueue = append(mapqueue, n) // check map keys when all types are settled
486485
n.Left = nil
487486
n.Right = nil
@@ -497,37 +496,28 @@ func typecheck1(n *Node, top int) (res *Node) {
497496
if l.Type.NotInHeap() {
498497
yyerror("chan of go:notinheap type not allowed")
499498
}
500-
t := types.NewChan(l.Type, n.TChanDir())
501-
n.Op = OTYPE
502-
n.Type = t
499+
500+
setTypeNode(n, types.NewChan(l.Type, n.TChanDir()))
503501
n.Left = nil
504502
n.ResetAux()
505503

506504
case OTSTRUCT:
507505
ok |= Etype
508-
n.Op = OTYPE
509-
n.Type = tostruct(n.List.Slice())
510-
if n.Type == nil || n.Type.Broke() {
506+
t := tostruct(n.List.Slice())
507+
if t.Broke() {
511508
n.Type = nil
512509
return n
513510
}
511+
setTypeNode(n, t)
514512
n.List.Set(nil)
515513

516514
case OTINTER:
517515
ok |= Etype
518-
n.Op = OTYPE
519-
n.Type = tointerface(n.List.Slice())
520-
if n.Type == nil {
521-
return n
522-
}
516+
setTypeNode(n, tointerface(n.List.Slice()))
523517

524518
case OTFUNC:
525519
ok |= Etype
526-
n.Op = OTYPE
527-
n.Type = functype(n.Left, n.List.Slice(), n.Rlist.Slice())
528-
if n.Type == nil {
529-
return n
530-
}
520+
setTypeNode(n, functype(n.Left, n.List.Slice(), n.Rlist.Slice()))
531521
n.Left = nil
532522
n.List.Set(nil)
533523
n.Rlist.Set(nil)
@@ -543,8 +533,7 @@ func typecheck1(n *Node, top int) (res *Node) {
543533
}
544534
if l.Op == OTYPE {
545535
ok |= Etype
546-
n.Op = OTYPE
547-
n.Type = types.NewPtr(l.Type)
536+
setTypeNode(n, types.NewPtr(l.Type))
548537
// Ensure l.Type gets dowidth'd for the backend. Issue 20174.
549538
// Don't checkwidth [...] arrays, though, since they
550539
// will be replaced by concrete-sized arrays. Issue 20333.
@@ -3683,8 +3672,7 @@ func typecheckdef(n *Node) {
36833672
defercheckwidth()
36843673
}
36853674
n.SetWalkdef(1)
3686-
n.Type = types.New(TFORW)
3687-
n.Type.Nod = asTypesNode(n)
3675+
setTypeNode(n, types.New(TFORW))
36883676
n.Type.Sym = n.Sym // TODO(gri) this also happens in typecheckdeftype(n) - where should it happen?
36893677
nerrors0 := nerrors
36903678
typecheckdeftype(n)
@@ -3951,3 +3939,10 @@ func deadcodeexpr(n *Node) *Node {
39513939
}
39523940
return n
39533941
}
3942+
3943+
// setTypeNode sets n to an OTYPE node representing t.
3944+
func setTypeNode(n *Node, t *types.Type) {
3945+
n.Op = OTYPE
3946+
n.Type = t
3947+
n.Type.Nod = asTypesNode(n)
3948+
}

test/fixedbugs/issue23823.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66

77
package p
88

9-
type I1 = interface {
9+
type I1 = interface { // ERROR "invalid recursive type"
1010
I2
1111
}
1212

13-
type I2 interface { // ERROR "invalid recursive type"
13+
type I2 interface {
1414
I1
1515
}

0 commit comments

Comments
 (0)