Skip to content

Commit e4de522

Browse files
committed
cmd/compile: fix Node.Etype overloading
Add helper methods that validate n.Op and convert to/from the appropriate type. Notably, there was a lot of code in walk.go that thought setting Etype=1 on an OADDR node affected escape analysis. Passes toolstash-check. TBR=marvin Change-Id: Ieae7c67225c1459c9719f9e6a748a25b975cf758 Reviewed-on: https://go-review.googlesource.com/99535 Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 91102bf commit e4de522

File tree

11 files changed

+98
-72
lines changed

11 files changed

+98
-72
lines changed

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,6 @@ func genhash(sym *types.Sym, t *types.Type) {
233233
nx := nod(OINDEX, np, ni)
234234
nx.SetBounded(true)
235235
na := nod(OADDR, nx, nil)
236-
na.Etype = 1 // no escape to heap
237236
call.List.Append(na)
238237
call.List.Append(nh)
239238
n.Nbody.Append(nod(OAS, nh, call))
@@ -258,7 +257,6 @@ func genhash(sym *types.Sym, t *types.Type) {
258257
call := nod(OCALL, hashel, nil)
259258
nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
260259
na := nod(OADDR, nx, nil)
261-
na.Etype = 1 // no escape to heap
262260
call.List.Append(na)
263261
call.List.Append(nh)
264262
fn.Nbody.Append(nod(OAS, nh, call))
@@ -274,7 +272,6 @@ func genhash(sym *types.Sym, t *types.Type) {
274272
call := nod(OCALL, hashel, nil)
275273
nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
276274
na := nod(OADDR, nx, nil)
277-
na.Etype = 1 // no escape to heap
278275
call.List.Append(na)
279276
call.List.Append(nh)
280277
call.List.Append(nodintconst(size))
@@ -518,9 +515,7 @@ func eqfield(p *Node, q *Node, field *types.Sym) *Node {
518515
// memequal(&p.field, &q.field [, size])
519516
func eqmem(p *Node, q *Node, field *types.Sym, size int64) *Node {
520517
nx := nod(OADDR, nodSym(OXDOT, p, field), nil)
521-
nx.Etype = 1 // does not escape
522518
ny := nod(OADDR, nodSym(OXDOT, q, field), nil)
523-
ny.Etype = 1 // does not escape
524519
nx = typecheck(nx, Erv)
525520
ny = typecheck(ny, Erv)
526521

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,7 +1461,7 @@ func (p *exporter) expr(n *Node) {
14611461
p.exprList(n.List)
14621462

14631463
case OCMPSTR, OCMPIFACE:
1464-
p.op(Op(n.Etype))
1464+
p.op(n.SubOp())
14651465
p.pos(n)
14661466
p.expr(n.Left)
14671467
p.expr(n.Right)
@@ -1527,7 +1527,7 @@ func (p *exporter) stmt(n *Node) {
15271527
case OASOP:
15281528
p.op(OASOP)
15291529
p.pos(n)
1530-
p.int(int(n.Etype))
1530+
p.op(n.SubOp())
15311531
p.expr(n.Left)
15321532
if p.bool(!n.Implicit()) {
15331533
p.expr(n.Right)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ func (p *importer) node() *Node {
11241124

11251125
case OASOP:
11261126
n := nodl(p.pos(), OASOP, nil, nil)
1127-
n.Etype = types.EType(p.int())
1127+
n.SetSubOp(p.op())
11281128
n.Left = p.expr()
11291129
if !p.bool() {
11301130
n.Right = nodintconst(1)

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

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -926,15 +926,15 @@ func (n *Node) stmtfmt(s fmt.State, mode fmtMode) {
926926

927927
case OASOP:
928928
if n.Implicit() {
929-
if Op(n.Etype) == OADD {
929+
if n.SubOp() == OADD {
930930
mode.Fprintf(s, "%v++", n.Left)
931931
} else {
932932
mode.Fprintf(s, "%v--", n.Left)
933933
}
934934
break
935935
}
936936

937-
mode.Fprintf(s, "%v %#v= %v", n.Left, Op(n.Etype), n.Right)
937+
mode.Fprintf(s, "%v %#v= %v", n.Left, n.SubOp(), n.Right)
938938

939939
case OAS2:
940940
if n.Colas() && !complexinit {
@@ -1274,15 +1274,15 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
12741274
mode.Fprintf(s, "map[%v]%v", n.Left, n.Right)
12751275

12761276
case OTCHAN:
1277-
switch types.ChanDir(n.Etype) {
1277+
switch n.TChanDir() {
12781278
case types.Crecv:
12791279
mode.Fprintf(s, "<-chan %v", n.Left)
12801280

12811281
case types.Csend:
12821282
mode.Fprintf(s, "chan<- %v", n.Left)
12831283

12841284
default:
1285-
if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && types.ChanDir(n.Left.Etype) == types.Crecv {
1285+
if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && n.Left.TChanDir() == types.Crecv {
12861286
mode.Fprintf(s, "chan (%v)", n.Left)
12871287
} else {
12881288
mode.Fprintf(s, "chan %v", n.Left)
@@ -1517,8 +1517,7 @@ func (n *Node) exprfmt(s fmt.State, prec int, mode fmtMode) {
15171517

15181518
case OCMPSTR, OCMPIFACE:
15191519
n.Left.exprfmt(s, nprec, mode)
1520-
// TODO(marvin): Fix Node.EType type union.
1521-
mode.Fprintf(s, " %#v ", Op(n.Etype))
1520+
mode.Fprintf(s, " %#v ", n.SubOp())
15221521
n.Right.exprfmt(s, nprec+1, mode)
15231522

15241523
default:
@@ -1593,7 +1592,7 @@ func (n *Node) nodedump(s fmt.State, flag FmtFlag, mode fmtMode) {
15931592
}
15941593

15951594
case OASOP:
1596-
mode.Fprintf(s, "%v-%v%j", n.Op, Op(n.Etype), n)
1595+
mode.Fprintf(s, "%v-%v%j", n.Op, n.SubOp(), n)
15971596

15981597
case OTYPE:
15991598
mode.Fprintf(s, "%v %v%j type=%v", n.Op, n.Sym, n, n.Type)

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,6 @@ func mkinlcall1(n, fn *Node, isddd bool) *Node {
10051005
}
10061006

10071007
retlabel := autolabel(".i")
1008-
retlabel.Etype = 1 // flag 'safe' for escape analysis (no backjumps)
10091008

10101009
inlgen++
10111010

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
654654
return p.nod(expr, OTMAP, p.typeExpr(expr.Key), p.typeExpr(expr.Value))
655655
case *syntax.ChanType:
656656
n := p.nod(expr, OTCHAN, p.typeExpr(expr.Elem), nil)
657-
n.Etype = types.EType(p.chanDir(expr.Dir))
657+
n.SetTChanDir(p.chanDir(expr.Dir))
658658
return n
659659

660660
case *syntax.TypeSwitchGuard:
@@ -902,7 +902,7 @@ func (p *noder) stmtFall(stmt syntax.Stmt, fallOK bool) *Node {
902902
if stmt.Op != 0 && stmt.Op != syntax.Def {
903903
n := p.nod(stmt, OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs))
904904
n.SetImplicit(stmt.Rhs == syntax.ImplicitOne)
905-
n.Etype = types.EType(p.binOp(stmt.Op))
905+
n.SetSubOp(p.binOp(stmt.Op))
906906
return n
907907
}
908908

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

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -526,15 +526,14 @@ func (o *Order) stmt(n *Node) {
526526
n.Left = o.safeExpr(n.Left)
527527
tmp1 := treecopy(n.Left, src.NoXPos)
528528
if tmp1.Op == OINDEXMAP {
529-
tmp1.Etype = 0 // now an rvalue not an lvalue
529+
tmp1.SetIndexMapLValue(false)
530530
}
531531
tmp1 = o.copyExpr(tmp1, n.Left.Type, false)
532-
// TODO(marvin): Fix Node.EType type union.
533-
n.Right = nod(Op(n.Etype), tmp1, n.Right)
532+
n.Right = nod(n.SubOp(), tmp1, n.Right)
534533
n.Right = typecheck(n.Right, Erv)
535534
n.Right = o.expr(n.Right, nil)
536-
n.Etype = 0
537535
n.Op = OAS
536+
n.ResetAux()
538537
o.mapAssign(n)
539538
o.cleanTemp(t)
540539

@@ -1015,7 +1014,7 @@ func (o *Order) expr(n, lhs *Node) *Node {
10151014
n.Right = o.expr(n.Right, nil)
10161015
needCopy := false
10171016

1018-
if n.Etype == 0 && instrumenting {
1017+
if !n.IndexMapLValue() && instrumenting {
10191018
// Race detector needs the copy so it can
10201019
// call treecopy on the result.
10211020
needCopy = true
@@ -1031,7 +1030,7 @@ func (o *Order) expr(n, lhs *Node) *Node {
10311030
// the map index, because the map access is going to
10321031
// be forced to happen immediately following this
10331032
// conversion (by the ordercopyexpr a few lines below).
1034-
if n.Etype == 0 && n.Right.Op == OARRAYBYTESTR {
1033+
if !n.IndexMapLValue() && n.Right.Op == OARRAYBYTESTR {
10351034
n.Right.Op = OARRAYBYTESTRTMP
10361035
needCopy = true
10371036
}

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

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,62 @@ type Node struct {
5555

5656
Esc uint16 // EscXXX
5757

58-
Op Op
59-
Etype types.EType // op for OASOP, etype for OTYPE, exclam for export, 6g saved reg, ChanDir for OTCHAN, for OINDEXMAP 1=LHS,0=RHS
58+
Op Op
59+
aux uint8
60+
}
61+
62+
func (n *Node) ResetAux() {
63+
n.aux = 0
64+
}
65+
66+
func (n *Node) SubOp() Op {
67+
switch n.Op {
68+
case OASOP, OCMPIFACE, OCMPSTR, ONAME:
69+
default:
70+
Fatalf("unexpected op: %v", n.Op)
71+
}
72+
return Op(n.aux)
73+
}
74+
75+
func (n *Node) SetSubOp(op Op) {
76+
switch n.Op {
77+
case OASOP, OCMPIFACE, OCMPSTR, ONAME:
78+
default:
79+
Fatalf("unexpected op: %v", n.Op)
80+
}
81+
n.aux = uint8(op)
82+
}
83+
84+
func (n *Node) IndexMapLValue() bool {
85+
if n.Op != OINDEXMAP {
86+
Fatalf("unexpected op: %v", n.Op)
87+
}
88+
return n.aux != 0
89+
}
90+
91+
func (n *Node) SetIndexMapLValue(b bool) {
92+
if n.Op != OINDEXMAP {
93+
Fatalf("unexpected op: %v", n.Op)
94+
}
95+
if b {
96+
n.aux = 1
97+
} else {
98+
n.aux = 0
99+
}
100+
}
101+
102+
func (n *Node) TChanDir() types.ChanDir {
103+
if n.Op != OTCHAN {
104+
Fatalf("unexpected op: %v", n.Op)
105+
}
106+
return types.ChanDir(n.aux)
107+
}
108+
109+
func (n *Node) SetTChanDir(dir types.ChanDir) {
110+
if n.Op != OTCHAN {
111+
Fatalf("unexpected op: %v", n.Op)
112+
}
113+
n.aux = uint8(dir)
60114
}
61115

62116
func (n *Node) IsSynthetic() bool {

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

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ func typecheck1(n *Node, top int) *Node {
263263
// n.Sym is a field/method name, not a variable.
264264
default:
265265
if n.Sym != nil {
266-
if n.Op == ONAME && n.Etype != 0 && top&Ecall == 0 {
266+
if n.Op == ONAME && n.SubOp() != 0 && top&Ecall == 0 {
267267
yyerror("use of builtin %v not in function call", n.Sym)
268268
n.Type = nil
269269
return n
@@ -300,7 +300,7 @@ func typecheck1(n *Node, top int) *Node {
300300
if n.Name.Decldepth == 0 {
301301
n.Name.Decldepth = decldepth
302302
}
303-
if n.Etype != 0 {
303+
if n.SubOp() != 0 {
304304
ok |= Ecall
305305
break
306306
}
@@ -428,11 +428,11 @@ func typecheck1(n *Node, top int) *Node {
428428
if l.Type.NotInHeap() {
429429
yyerror("chan of go:notinheap type not allowed")
430430
}
431-
t := types.NewChan(l.Type, types.ChanDir(n.Etype)) // TODO(marvin): Fix Node.EType type union.
431+
t := types.NewChan(l.Type, n.TChanDir())
432432
n.Op = OTYPE
433433
n.Type = t
434434
n.Left = nil
435-
n.Etype = 0
435+
n.ResetAux()
436436

437437
case OTSTRUCT:
438438
ok |= Etype
@@ -540,7 +540,7 @@ func typecheck1(n *Node, top int) *Node {
540540
return n
541541
}
542542
// TODO(marvin): Fix Node.EType type union.
543-
op = Op(n.Etype)
543+
op = n.SubOp()
544544
} else {
545545
ok |= Erv
546546
n.Left = typecheck(n.Left, Erv)
@@ -712,9 +712,9 @@ func typecheck1(n *Node, top int) *Node {
712712

713713
if et == TSTRING {
714714
if iscmp[n.Op] {
715-
// TODO(marvin): Fix Node.EType type union.
716-
n.Etype = types.EType(n.Op)
715+
ot := n.Op
717716
n.Op = OCMPSTR
717+
n.SetSubOp(ot)
718718
} else if n.Op == OADD {
719719
// create OADDSTR node with list of strings in x + y + z + (w + v) + ...
720720
n.Op = OADDSTR
@@ -743,9 +743,9 @@ func typecheck1(n *Node, top int) *Node {
743743
} else if r.Op == OLITERAL && r.Val().Ctype() == CTNIL {
744744
} else // leave alone for back end
745745
if r.Type.IsInterface() == l.Type.IsInterface() {
746-
// TODO(marvin): Fix Node.EType type union.
747-
n.Etype = types.EType(n.Op)
746+
ot := n.Op
748747
n.Op = OCMPIFACE
748+
n.SetSubOp(ot)
749749
}
750750
}
751751

@@ -1026,13 +1026,13 @@ func typecheck1(n *Node, top int) *Node {
10261026
}
10271027

10281028
case TMAP:
1029-
n.Etype = 0
10301029
n.Right = defaultlit(n.Right, t.Key())
10311030
if n.Right.Type != nil {
10321031
n.Right = assignconv(n.Right, t.Key(), "map index")
10331032
}
10341033
n.Type = t.Val()
10351034
n.Op = OINDEXMAP
1035+
n.ResetAux()
10361036
}
10371037

10381038
case ORECV:
@@ -1088,10 +1088,6 @@ func typecheck1(n *Node, top int) *Node {
10881088
return n
10891089
}
10901090
n.Right = assignconv(r, t.Elem(), "send")
1091-
1092-
// TODO: more aggressive
1093-
n.Etype = 0
1094-
10951091
n.Type = nil
10961092

10971093
case OSLICE, OSLICE3:
@@ -1177,15 +1173,13 @@ func typecheck1(n *Node, top int) *Node {
11771173

11781174
l := n.Left
11791175

1180-
if l.Op == ONAME && l.Etype != 0 {
1181-
// TODO(marvin): Fix Node.EType type union.
1182-
if n.Isddd() && Op(l.Etype) != OAPPEND {
1176+
if l.Op == ONAME && l.SubOp() != 0 {
1177+
if n.Isddd() && l.SubOp() != OAPPEND {
11831178
yyerror("invalid use of ... with builtin %v", l)
11841179
}
11851180

11861181
// builtin: OLEN, OCAP, etc.
1187-
// TODO(marvin): Fix Node.EType type union.
1188-
n.Op = Op(l.Etype)
1182+
n.Op = l.SubOp()
11891183
n.Left = n.Right
11901184
n.Right = nil
11911185
n = typecheck1(n, top)
@@ -3214,7 +3208,7 @@ func checkassign(stmt *Node, n *Node) {
32143208
return
32153209
}
32163210
if n.Op == OINDEXMAP {
3217-
n.Etype = 1
3211+
n.SetIndexMapLValue(true)
32183212
return
32193213
}
32203214

@@ -3705,7 +3699,7 @@ func typecheckdef(n *Node) {
37053699
break
37063700
}
37073701
if n.Name.Defn == nil {
3708-
if n.Etype != 0 { // like OPRINTN
3702+
if n.SubOp() != 0 { // like OPRINTN
37093703
break
37103704
}
37113705
if nsavederrors+nerrors > 0 {

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,16 +114,15 @@ func lexinit() {
114114
}
115115

116116
for _, s := range builtinFuncs {
117-
// TODO(marvin): Fix Node.EType type union.
118117
s2 := builtinpkg.Lookup(s.name)
119118
s2.Def = asTypesNode(newname(s2))
120-
asNode(s2.Def).Etype = types.EType(s.op)
119+
asNode(s2.Def).SetSubOp(s.op)
121120
}
122121

123122
for _, s := range unsafeFuncs {
124123
s2 := unsafepkg.Lookup(s.name)
125124
s2.Def = asTypesNode(newname(s2))
126-
asNode(s2.Def).Etype = types.EType(s.op)
125+
asNode(s2.Def).SetSubOp(s.op)
127126
}
128127

129128
types.Idealstring = types.New(TSTRING)

0 commit comments

Comments
 (0)