Commit ed70f37e authored by Aliaksandr Valialkin's avatar Aliaksandr Valialkin Committed by Matthew Dempsky

cmd/compile: pack bool fields in Node, Name, Func and Type structs to bitsets

This reduces compiler memory usage by up to 4% - see compilebench
results below.

name       old time/op     new time/op     delta
Template       245ms ± 4%      241ms ± 2%  -1.88%  (p=0.029 n=10+10)
Unicode        126ms ± 3%      124ms ± 3%    ~     (p=0.105 n=10+10)
GoTypes        805ms ± 2%      813ms ± 3%    ~     (p=0.515 n=8+10)
Compiler       3.95s ± 2%      3.83s ± 1%  -2.96%  (p=0.000 n=9+10)
MakeBash       47.4s ± 4%      46.6s ± 1%  -1.59%  (p=0.028 n=9+10)

name       old user-ns/op  new user-ns/op  delta
Template        324M ± 5%       326M ± 3%    ~     (p=0.935 n=10+10)
Unicode         186M ± 5%       178M ±10%    ~     (p=0.067 n=9+10)
GoTypes        1.08G ± 7%      1.09G ± 4%    ~     (p=0.956 n=10+10)
Compiler       5.34G ± 4%      5.31G ± 1%    ~     (p=0.501 n=10+8)

name       old alloc/op    new alloc/op    delta
Template      41.0MB ± 0%     39.8MB ± 0%  -3.03%  (p=0.000 n=10+10)
Unicode       32.3MB ± 0%     31.0MB ± 0%  -4.13%  (p=0.000 n=10+10)
GoTypes        119MB ± 0%      116MB ± 0%  -2.39%  (p=0.000 n=10+10)
Compiler       499MB ± 0%      487MB ± 0%  -2.48%  (p=0.000 n=10+10)

name       old allocs/op   new allocs/op   delta
Template        380k ± 1%       379k ± 1%    ~     (p=0.436 n=10+10)
Unicode         324k ± 1%       324k ± 0%    ~     (p=0.853 n=10+10)
GoTypes        1.15M ± 0%      1.15M ± 0%    ~     (p=0.481 n=10+10)
Compiler       4.41M ± 0%      4.41M ± 0%  -0.12%  (p=0.007 n=10+10)

name       old text-bytes  new text-bytes  delta
HelloSize       623k ± 0%       623k ± 0%    ~     (all equal)
CmdGoSize      6.64M ± 0%      6.64M ± 0%    ~     (all equal)

name       old data-bytes  new data-bytes  delta
HelloSize      5.81k ± 0%      5.81k ± 0%    ~     (all equal)
CmdGoSize       238k ± 0%       238k ± 0%    ~     (all equal)

name       old bss-bytes   new bss-bytes   delta
HelloSize       134k ± 0%       134k ± 0%    ~     (all equal)
CmdGoSize       152k ± 0%       152k ± 0%    ~     (all equal)

name       old exe-bytes   new exe-bytes   delta
HelloSize       967k ± 0%       967k ± 0%    ~     (all equal)
CmdGoSize      10.2M ± 0%      10.2M ± 0%    ~     (all equal)

Change-Id: I1f40af738254892bd6c8ba2eb43390b175753d52
Reviewed-on: https://go-review.googlesource.com/37445Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent fbf4dd91
...@@ -33,7 +33,7 @@ func defframe(ptxt *obj.Prog) { ...@@ -33,7 +33,7 @@ func defframe(ptxt *obj.Prog) {
// iterate through declarations - they are sorted in decreasing xoffset order. // iterate through declarations - they are sorted in decreasing xoffset order.
for _, n := range gc.Curfn.Func.Dcl { for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero { if !n.Name.Needzero() {
continue continue
} }
if n.Class != gc.PAUTO { if n.Class != gc.PAUTO {
......
...@@ -27,7 +27,7 @@ func defframe(ptxt *obj.Prog) { ...@@ -27,7 +27,7 @@ func defframe(ptxt *obj.Prog) {
lo := hi lo := hi
r0 := uint32(0) r0 := uint32(0)
for _, n := range gc.Curfn.Func.Dcl { for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero { if !n.Name.Needzero() {
continue continue
} }
if n.Class != gc.PAUTO { if n.Class != gc.PAUTO {
......
...@@ -35,7 +35,7 @@ func defframe(ptxt *obj.Prog) { ...@@ -35,7 +35,7 @@ func defframe(ptxt *obj.Prog) {
// iterate through declarations - they are sorted in decreasing xoffset order. // iterate through declarations - they are sorted in decreasing xoffset order.
for _, n := range gc.Curfn.Func.Dcl { for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero { if !n.Name.Needzero() {
continue continue
} }
if n.Class != gc.PAUTO { if n.Class != gc.PAUTO {
......
...@@ -84,10 +84,10 @@ func algtype(t *Type) AlgKind { ...@@ -84,10 +84,10 @@ func algtype(t *Type) AlgKind {
// If it returns ANOEQ, it also returns the component type of t that // If it returns ANOEQ, it also returns the component type of t that
// makes it incomparable. // makes it incomparable.
func algtype1(t *Type) (AlgKind, *Type) { func algtype1(t *Type) (AlgKind, *Type) {
if t.Broke { if t.Broke() {
return AMEM, nil return AMEM, nil
} }
if t.Noalg { if t.Noalg() {
return ANOEQ, t return ANOEQ, t
} }
...@@ -227,7 +227,7 @@ func genhash(sym *Sym, t *Type) { ...@@ -227,7 +227,7 @@ func genhash(sym *Sym, t *Type) {
ni := newname(lookup("i")) ni := newname(lookup("i"))
ni.Type = Types[TINT] ni.Type = Types[TINT]
n.List.Set1(ni) n.List.Set1(ni)
n.Colas = true n.SetColas(true)
colasdefn(n.List.Slice(), n) colasdefn(n.List.Slice(), n)
ni = n.List.First() ni = n.List.First()
...@@ -235,7 +235,7 @@ func genhash(sym *Sym, t *Type) { ...@@ -235,7 +235,7 @@ func genhash(sym *Sym, t *Type) {
call := nod(OCALL, hashel, nil) call := nod(OCALL, hashel, nil)
nx := nod(OINDEX, np, ni) nx := nod(OINDEX, np, ni)
nx.Bounded = true nx.SetBounded(true)
na := nod(OADDR, nx, nil) na := nod(OADDR, nx, nil)
na.Etype = 1 // no escape to heap na.Etype = 1 // no escape to heap
call.List.Append(na) call.List.Append(na)
...@@ -298,7 +298,7 @@ func genhash(sym *Sym, t *Type) { ...@@ -298,7 +298,7 @@ func genhash(sym *Sym, t *Type) {
funcbody(fn) funcbody(fn)
Curfn = fn Curfn = fn
fn.Func.Dupok = true fn.Func.SetDupok(true)
fn = typecheck(fn, Etop) fn = typecheck(fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil Curfn = nil
...@@ -406,16 +406,16 @@ func geneq(sym *Sym, t *Type) { ...@@ -406,16 +406,16 @@ func geneq(sym *Sym, t *Type) {
ni := newname(lookup("i")) ni := newname(lookup("i"))
ni.Type = Types[TINT] ni.Type = Types[TINT]
nrange.List.Set1(ni) nrange.List.Set1(ni)
nrange.Colas = true nrange.SetColas(true)
colasdefn(nrange.List.Slice(), nrange) colasdefn(nrange.List.Slice(), nrange)
ni = nrange.List.First() ni = nrange.List.First()
// if p[i] != q[i] { return false } // if p[i] != q[i] { return false }
nx := nod(OINDEX, np, ni) nx := nod(OINDEX, np, ni)
nx.Bounded = true nx.SetBounded(true)
ny := nod(OINDEX, nq, ni) ny := nod(OINDEX, nq, ni)
ny.Bounded = true ny.SetBounded(true)
nif := nod(OIF, nil, nil) nif := nod(OIF, nil, nil)
nif.Left = nod(ONE, nx, ny) nif.Left = nod(ONE, nx, ny)
...@@ -490,7 +490,7 @@ func geneq(sym *Sym, t *Type) { ...@@ -490,7 +490,7 @@ func geneq(sym *Sym, t *Type) {
funcbody(fn) funcbody(fn)
Curfn = fn Curfn = fn
fn.Func.Dupok = true fn.Func.SetDupok(true)
fn = typecheck(fn, Etop) fn = typecheck(fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typecheckslice(fn.Nbody.Slice(), Etop)
Curfn = nil Curfn = nil
......
...@@ -124,8 +124,8 @@ func dowidth(t *Type) { ...@@ -124,8 +124,8 @@ func dowidth(t *Type) {
} }
if t.Width == -2 { if t.Width == -2 {
if !t.Broke { if !t.Broke() {
t.Broke = true t.SetBroke(true)
yyerrorl(t.Pos, "invalid recursive type %v", t) yyerrorl(t.Pos, "invalid recursive type %v", t)
} }
...@@ -135,7 +135,7 @@ func dowidth(t *Type) { ...@@ -135,7 +135,7 @@ func dowidth(t *Type) {
// break infinite recursion if the broken recursive type // break infinite recursion if the broken recursive type
// is referenced again // is referenced again
if t.Broke && t.Width == 0 { if t.Broke() && t.Width == 0 {
return return
} }
...@@ -228,7 +228,7 @@ func dowidth(t *Type) { ...@@ -228,7 +228,7 @@ func dowidth(t *Type) {
checkwidth(t.Key()) checkwidth(t.Key())
case TFORW: // should have been filled in case TFORW: // should have been filled in
if !t.Broke { if !t.Broke() {
yyerror("invalid recursive type %v", t) yyerror("invalid recursive type %v", t)
} }
w = 1 // anything will do w = 1 // anything will do
...@@ -249,9 +249,9 @@ func dowidth(t *Type) { ...@@ -249,9 +249,9 @@ func dowidth(t *Type) {
break break
} }
if t.isDDDArray() { if t.isDDDArray() {
if !t.Broke { if !t.Broke() {
yyerror("use of [...] array outside of array literal") yyerror("use of [...] array outside of array literal")
t.Broke = true t.SetBroke(true)
} }
break break
} }
...@@ -356,10 +356,10 @@ func checkwidth(t *Type) { ...@@ -356,10 +356,10 @@ func checkwidth(t *Type) {
return return
} }
if t.Deferwidth { if t.Deferwidth() {
return return
} }
t.Deferwidth = true t.SetDeferwidth(true)
deferredTypeStack = append(deferredTypeStack, t) deferredTypeStack = append(deferredTypeStack, t)
} }
...@@ -379,7 +379,7 @@ func resumecheckwidth() { ...@@ -379,7 +379,7 @@ func resumecheckwidth() {
for len(deferredTypeStack) > 0 { for len(deferredTypeStack) > 0 {
t := deferredTypeStack[len(deferredTypeStack)-1] t := deferredTypeStack[len(deferredTypeStack)-1]
deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1] deferredTypeStack = deferredTypeStack[:len(deferredTypeStack)-1]
t.Deferwidth = false t.SetDeferwidth(false)
dowidth(t) dowidth(t)
} }
......
...@@ -702,7 +702,7 @@ func (p *exporter) typ(t *Type) { ...@@ -702,7 +702,7 @@ func (p *exporter) typ(t *Type) {
p.paramList(sig.Recvs(), inlineable) p.paramList(sig.Recvs(), inlineable)
p.paramList(sig.Params(), inlineable) p.paramList(sig.Params(), inlineable)
p.paramList(sig.Results(), inlineable) p.paramList(sig.Results(), inlineable)
p.bool(m.Nointerface) // record go:nointerface pragma value (see also #16243) p.bool(m.Nointerface()) // record go:nointerface pragma value (see also #16243)
var f *Func var f *Func
if inlineable { if inlineable {
...@@ -921,7 +921,7 @@ func (p *exporter) paramList(params *Type, numbered bool) { ...@@ -921,7 +921,7 @@ func (p *exporter) paramList(params *Type, numbered bool) {
func (p *exporter) param(q *Field, n int, numbered bool) { func (p *exporter) param(q *Field, n int, numbered bool) {
t := q.Type t := q.Type
if q.Isddd { if q.Isddd() {
// create a fake type to encode ... just for the p.typ call // create a fake type to encode ... just for the p.typ call
t = typDDDField(t.Elem()) t = typDDDField(t.Elem())
} }
...@@ -1183,7 +1183,7 @@ func (p *exporter) expr(n *Node) { ...@@ -1183,7 +1183,7 @@ func (p *exporter) expr(n *Node) {
// } // }
// from exprfmt (fmt.go) // from exprfmt (fmt.go)
for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) { for n != nil && n.Implicit() && (n.Op == OIND || n.Op == OADDR) {
n = n.Left n = n.Left
} }
...@@ -1256,7 +1256,7 @@ func (p *exporter) expr(n *Node) { ...@@ -1256,7 +1256,7 @@ func (p *exporter) expr(n *Node) {
case OPTRLIT: case OPTRLIT:
p.op(OPTRLIT) p.op(OPTRLIT)
p.expr(n.Left) p.expr(n.Left)
p.bool(n.Implicit) p.bool(n.Implicit())
case OSTRUCTLIT: case OSTRUCTLIT:
p.op(OSTRUCTLIT) p.op(OSTRUCTLIT)
...@@ -1337,8 +1337,8 @@ func (p *exporter) expr(n *Node) { ...@@ -1337,8 +1337,8 @@ func (p *exporter) expr(n *Node) {
} }
// only append() calls may contain '...' arguments // only append() calls may contain '...' arguments
if op == OAPPEND { if op == OAPPEND {
p.bool(n.Isddd) p.bool(n.Isddd())
} else if n.Isddd { } else if n.Isddd() {
Fatalf("exporter: unexpected '...' with %s call", opnames[op]) Fatalf("exporter: unexpected '...' with %s call", opnames[op])
} }
...@@ -1346,7 +1346,7 @@ func (p *exporter) expr(n *Node) { ...@@ -1346,7 +1346,7 @@ func (p *exporter) expr(n *Node) {
p.op(OCALL) p.op(OCALL)
p.expr(n.Left) p.expr(n.Left)
p.exprList(n.List) p.exprList(n.List)
p.bool(n.Isddd) p.bool(n.Isddd())
case OMAKEMAP, OMAKECHAN, OMAKESLICE: case OMAKEMAP, OMAKECHAN, OMAKESLICE:
p.op(op) // must keep separate from OMAKE for importer p.op(op) // must keep separate from OMAKE for importer
...@@ -1446,7 +1446,7 @@ func (p *exporter) stmt(n *Node) { ...@@ -1446,7 +1446,7 @@ func (p *exporter) stmt(n *Node) {
p.op(OASOP) p.op(OASOP)
p.int(int(n.Etype)) p.int(int(n.Etype))
p.expr(n.Left) p.expr(n.Left)
if p.bool(!n.Implicit) { if p.bool(!n.Implicit()) {
p.expr(n.Right) p.expr(n.Right)
} }
......
...@@ -688,7 +688,7 @@ func (p *importer) param(named bool) *Field { ...@@ -688,7 +688,7 @@ func (p *importer) param(named bool) *Field {
if f.Type.Etype == TDDDFIELD { if f.Type.Etype == TDDDFIELD {
// TDDDFIELD indicates wrapped ... slice type // TDDDFIELD indicates wrapped ... slice type
f.Type = typSlice(f.Type.DDDField()) f.Type = typSlice(f.Type.DDDField())
f.Isddd = true f.SetIsddd(true)
} }
if named { if named {
...@@ -898,7 +898,7 @@ func (p *importer) node() *Node { ...@@ -898,7 +898,7 @@ func (p *importer) node() *Node {
if n.Op == OCOMPLIT { if n.Op == OCOMPLIT {
// Special case for &T{...}: turn into (*T){...}. // Special case for &T{...}: turn into (*T){...}.
n.Right = nod(OIND, n.Right, nil) n.Right = nod(OIND, n.Right, nil)
n.Right.Implicit = true n.Right.SetImplicit(true)
} else { } else {
n = nod(OADDR, n, nil) n = nod(OADDR, n, nil)
} }
...@@ -975,7 +975,7 @@ func (p *importer) node() *Node { ...@@ -975,7 +975,7 @@ func (p *importer) node() *Node {
n := builtinCall(op) n := builtinCall(op)
n.List.Set(p.exprList()) n.List.Set(p.exprList())
if op == OAPPEND { if op == OAPPEND {
n.Isddd = p.bool() n.SetIsddd(p.bool())
} }
return n return n
...@@ -985,7 +985,7 @@ func (p *importer) node() *Node { ...@@ -985,7 +985,7 @@ func (p *importer) node() *Node {
case OCALL: case OCALL:
n := nod(OCALL, p.expr(), nil) n := nod(OCALL, p.expr(), nil)
n.List.Set(p.exprList()) n.List.Set(p.exprList())
n.Isddd = p.bool() n.SetIsddd(p.bool())
return n return n
case OMAKEMAP, OMAKECHAN, OMAKESLICE: case OMAKEMAP, OMAKECHAN, OMAKESLICE:
...@@ -1045,7 +1045,7 @@ func (p *importer) node() *Node { ...@@ -1045,7 +1045,7 @@ func (p *importer) node() *Node {
n.Left = p.expr() n.Left = p.expr()
if !p.bool() { if !p.bool() {
n.Right = nodintconst(1) n.Right = nodintconst(1)
n.Implicit = true n.SetImplicit(true)
} else { } else {
n.Right = p.expr() n.Right = p.expr()
} }
......
// Copyright 2017 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 gc
type bitset8 uint8
func (f *bitset8) set(mask uint8, b bool) {
if b {
*(*uint8)(f) |= mask
} else {
*(*uint8)(f) &^= mask
}
}
type bitset16 uint16
func (f *bitset16) set(mask uint16, b bool) {
if b {
*(*uint16)(f) |= mask
} else {
*(*uint16)(f) &^= mask
}
}
...@@ -33,9 +33,9 @@ func closurehdr(ntype *Node) { ...@@ -33,9 +33,9 @@ func closurehdr(ntype *Node) {
name = newname(name.Sym) name = newname(name.Sym)
} }
a := nod(ODCLFIELD, name, n1.Right) a := nod(ODCLFIELD, name, n1.Right)
a.Isddd = n1.Isddd a.SetIsddd(n1.Isddd())
if name != nil { if name != nil {
name.Isddd = a.Isddd name.SetIsddd(a.Isddd())
} }
ntype.List.Append(a) ntype.List.Append(a)
} }
...@@ -104,8 +104,8 @@ func closurebody(body []*Node) *Node { ...@@ -104,8 +104,8 @@ func closurebody(body []*Node) *Node {
func typecheckclosure(func_ *Node, top int) { func typecheckclosure(func_ *Node, top int) {
for _, ln := range func_.Func.Cvars.Slice() { for _, ln := range func_.Func.Cvars.Slice() {
n := ln.Name.Defn n := ln.Name.Defn
if !n.Name.Captured { if !n.Name.Captured() {
n.Name.Captured = true n.Name.SetCaptured(true)
if n.Name.Decldepth == 0 { if n.Name.Decldepth == 0 {
Fatalf("typecheckclosure: var %S does not have decldepth assigned", n) Fatalf("typecheckclosure: var %S does not have decldepth assigned", n)
} }
...@@ -113,7 +113,7 @@ func typecheckclosure(func_ *Node, top int) { ...@@ -113,7 +113,7 @@ func typecheckclosure(func_ *Node, top int) {
// Ignore assignments to the variable in straightline code // Ignore assignments to the variable in straightline code
// preceding the first capturing by a closure. // preceding the first capturing by a closure.
if n.Name.Decldepth == decldepth { if n.Name.Decldepth == decldepth {
n.Assigned = false n.SetAssigned(false)
} }
} }
} }
...@@ -272,10 +272,10 @@ func capturevars(xfunc *Node) { ...@@ -272,10 +272,10 @@ func capturevars(xfunc *Node) {
outermost := v.Name.Defn outermost := v.Name.Defn
// out parameters will be assigned to implicitly upon return. // out parameters will be assigned to implicitly upon return.
if outer.Class != PPARAMOUT && !outermost.Addrtaken && !outermost.Assigned && v.Type.Width <= 128 { if outer.Class != PPARAMOUT && !outermost.Addrtaken() && !outermost.Assigned() && v.Type.Width <= 128 {
v.Name.Byval = true v.Name.SetByval(true)
} else { } else {
outermost.Addrtaken = true outermost.SetAddrtaken(true)
outer = nod(OADDR, outer, nil) outer = nod(OADDR, outer, nil)
} }
...@@ -285,10 +285,10 @@ func capturevars(xfunc *Node) { ...@@ -285,10 +285,10 @@ func capturevars(xfunc *Node) {
name = v.Name.Curfn.Func.Nname.Sym name = v.Name.Curfn.Func.Nname.Sym
} }
how := "ref" how := "ref"
if v.Name.Byval { if v.Name.Byval() {
how = "value" how = "value"
} }
Warnl(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Addrtaken, outermost.Assigned, int32(v.Type.Width)) Warnl(v.Pos, "%v capturing by %s: %v (addr=%v assign=%v width=%d)", name, how, v.Sym, outermost.Addrtaken(), outermost.Assigned(), int32(v.Type.Width))
} }
outer = typecheck(outer, Erv) outer = typecheck(outer, Erv)
...@@ -333,7 +333,7 @@ func transformclosure(xfunc *Node) { ...@@ -333,7 +333,7 @@ func transformclosure(xfunc *Node) {
} }
fld := newField() fld := newField()
fld.Funarg = FunargParams fld.Funarg = FunargParams
if v.Name.Byval { if v.Name.Byval() {
// If v is captured by value, we merely downgrade it to PPARAM. // If v is captured by value, we merely downgrade it to PPARAM.
v.Class = PPARAM v.Class = PPARAM
...@@ -383,14 +383,14 @@ func transformclosure(xfunc *Node) { ...@@ -383,14 +383,14 @@ func transformclosure(xfunc *Node) {
cv := nod(OCLOSUREVAR, nil, nil) cv := nod(OCLOSUREVAR, nil, nil)
cv.Type = v.Type cv.Type = v.Type
if !v.Name.Byval { if !v.Name.Byval() {
cv.Type = ptrto(v.Type) cv.Type = ptrto(v.Type)
} }
offset = Rnd(offset, int64(cv.Type.Align)) offset = Rnd(offset, int64(cv.Type.Align))
cv.Xoffset = offset cv.Xoffset = offset
offset += cv.Type.Width offset += cv.Type.Width
if v.Name.Byval && v.Type.Width <= int64(2*Widthptr) { if v.Name.Byval() && v.Type.Width <= int64(2*Widthptr) {
// If it is a small variable captured by value, downgrade it to PAUTO. // If it is a small variable captured by value, downgrade it to PAUTO.
v.Class = PAUTO v.Class = PAUTO
v.Ullman = 1 v.Ullman = 1
...@@ -402,11 +402,11 @@ func transformclosure(xfunc *Node) { ...@@ -402,11 +402,11 @@ func transformclosure(xfunc *Node) {
addr := newname(lookupf("&%s", v.Sym.Name)) addr := newname(lookupf("&%s", v.Sym.Name))
addr.Name.Param.Ntype = nod(OIND, typenod(v.Type), nil) addr.Name.Param.Ntype = nod(OIND, typenod(v.Type), nil)
addr.Class = PAUTO addr.Class = PAUTO
addr.Used = true addr.SetUsed(true)
addr.Name.Curfn = xfunc addr.Name.Curfn = xfunc
xfunc.Func.Dcl = append(xfunc.Func.Dcl, addr) xfunc.Func.Dcl = append(xfunc.Func.Dcl, addr)
v.Name.Param.Heapaddr = addr v.Name.Param.Heapaddr = addr
if v.Name.Byval { if v.Name.Byval() {
cv = nod(OADDR, cv, nil) cv = nod(OADDR, cv, nil)
} }
body = append(body, nod(OAS, addr, cv)) body = append(body, nod(OAS, addr, cv))
...@@ -417,7 +417,7 @@ func transformclosure(xfunc *Node) { ...@@ -417,7 +417,7 @@ func transformclosure(xfunc *Node) {
typecheckslice(body, Etop) typecheckslice(body, Etop)
walkstmtlist(body) walkstmtlist(body)
xfunc.Func.Enter.Set(body) xfunc.Func.Enter.Set(body)
xfunc.Func.Needctxt = true xfunc.Func.SetNeedctxt(true)
} }
} }
...@@ -484,7 +484,7 @@ func walkclosure(func_ *Node, init *Nodes) *Node { ...@@ -484,7 +484,7 @@ func walkclosure(func_ *Node, init *Nodes) *Node {
continue continue
} }
typ1 := typenod(v.Type) typ1 := typenod(v.Type)
if !v.Name.Byval { if !v.Name.Byval() {
typ1 = nod(OIND, typ1, nil) typ1 = nod(OIND, typ1, nil)
} }
typ.List.Append(nod(ODCLFIELD, newname(v.Sym), typ1)) typ.List.Append(nod(ODCLFIELD, newname(v.Sym), typ1))
...@@ -492,7 +492,7 @@ func walkclosure(func_ *Node, init *Nodes) *Node { ...@@ -492,7 +492,7 @@ func walkclosure(func_ *Node, init *Nodes) *Node {
clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil)) clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil))
clos.Esc = func_.Esc clos.Esc = func_.Esc
clos.Right.Implicit = true clos.Right.SetImplicit(true)
clos.List.Set(append([]*Node{nod(OCFUNC, func_.Func.Closure.Func.Nname, nil)}, func_.Func.Enter.Slice()...)) clos.List.Set(append([]*Node{nod(OCFUNC, func_.Func.Closure.Func.Nname, nil)}, func_.Func.Enter.Slice()...))
// Force type conversion from *struct to the func type. // Force type conversion from *struct to the func type.
...@@ -587,8 +587,8 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { ...@@ -587,8 +587,8 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
xfunc.Func.Dcl = append(xfunc.Func.Dcl, n) xfunc.Func.Dcl = append(xfunc.Func.Dcl, n)
callargs = append(callargs, n) callargs = append(callargs, n)
fld := nod(ODCLFIELD, n, typenod(t.Type)) fld := nod(ODCLFIELD, n, typenod(t.Type))
if t.Isddd { if t.Isddd() {
fld.Isddd = true fld.SetIsddd(true)
ddd = true ddd = true
} }
...@@ -608,7 +608,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { ...@@ -608,7 +608,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
xtype.Rlist.Set(l) xtype.Rlist.Set(l)
xfunc.Func.Dupok = true xfunc.Func.SetDupok(true)
xfunc.Func.Nname = newfuncname(sym) xfunc.Func.Nname = newfuncname(sym)
xfunc.Func.Nname.Sym.Flags |= SymExported // disable export xfunc.Func.Nname.Sym.Flags |= SymExported // disable export
xfunc.Func.Nname.Name.Param.Ntype = xtype xfunc.Func.Nname.Name.Param.Ntype = xtype
...@@ -617,7 +617,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { ...@@ -617,7 +617,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
// Declare and initialize variable holding receiver. // Declare and initialize variable holding receiver.
xfunc.Func.Needctxt = true xfunc.Func.SetNeedctxt(true)
cv := nod(OCLOSUREVAR, nil, nil) cv := nod(OCLOSUREVAR, nil, nil)
cv.Xoffset = int64(Widthptr) cv.Xoffset = int64(Widthptr)
cv.Type = rcvrtype cv.Type = rcvrtype
...@@ -627,9 +627,9 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { ...@@ -627,9 +627,9 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
ptr := nod(ONAME, nil, nil) ptr := nod(ONAME, nil, nil)
ptr.Sym = lookup("rcvr") ptr.Sym = lookup("rcvr")
ptr.Class = PAUTO ptr.Class = PAUTO
ptr.Addable = true ptr.SetAddable(true)
ptr.Ullman = 1 ptr.Ullman = 1
ptr.Used = true ptr.SetUsed(true)
ptr.Name.Curfn = xfunc ptr.Name.Curfn = xfunc
ptr.Xoffset = 0 ptr.Xoffset = 0
xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr) xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr)
...@@ -644,7 +644,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node { ...@@ -644,7 +644,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
call := nod(OCALL, nodSym(OXDOT, ptr, meth), nil) call := nod(OCALL, nodSym(OXDOT, ptr, meth), nil)
call.List.Set(callargs) call.List.Set(callargs)
call.Isddd = ddd call.SetIsddd(ddd)
if t0.Results().NumFields() == 0 { if t0.Results().NumFields() == 0 {
body = append(body, call) body = append(body, call)
} else { } else {
...@@ -688,7 +688,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node { ...@@ -688,7 +688,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil)) clos := nod(OCOMPLIT, nil, nod(OIND, typ, nil))
clos.Esc = n.Esc clos.Esc = n.Esc
clos.Right.Implicit = true clos.Right.SetImplicit(true)
clos.List.Set1(nod(OCFUNC, n.Func.Nname, nil)) clos.List.Set1(nod(OCFUNC, n.Func.Nname, nil))
clos.List.Append(n.Left) clos.List.Append(n.Left)
......
...@@ -371,11 +371,11 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node { ...@@ -371,11 +371,11 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node {
return n return n
bad: bad:
if !n.Diag { if !n.Diag() {
if !t.Broke { if !t.Broke() {
yyerror("cannot convert %v to type %v", n, t) yyerror("cannot convert %v to type %v", n, t)
} }
n.Diag = true n.SetDiag(true)
} }
if n.Type.IsUntyped() { if n.Type.IsUntyped() {
...@@ -702,9 +702,9 @@ func evconst(n *Node) { ...@@ -702,9 +702,9 @@ func evconst(n *Node) {
switch uint32(n.Op)<<16 | uint32(v.Ctype()) { switch uint32(n.Op)<<16 | uint32(v.Ctype()) {
default: default:
if !n.Diag { if !n.Diag() {
yyerror("illegal constant expression %v %v", n.Op, nl.Type) yyerror("illegal constant expression %v %v", n.Op, nl.Type)
n.Diag = true n.SetDiag(true)
} }
return return
...@@ -964,9 +964,9 @@ func evconst(n *Node) { ...@@ -964,9 +964,9 @@ func evconst(n *Node) {
// The default case above would print 'ideal % ideal', // The default case above would print 'ideal % ideal',
// which is not quite an ideal error. // which is not quite an ideal error.
case OMOD_ | CTFLT_: case OMOD_ | CTFLT_:
if !n.Diag { if !n.Diag() {
yyerror("illegal constant expression: floating-point %% operation") yyerror("illegal constant expression: floating-point %% operation")
n.Diag = true n.SetDiag(true)
} }
return return
...@@ -1190,9 +1190,9 @@ setfalse: ...@@ -1190,9 +1190,9 @@ setfalse:
return return
illegal: illegal:
if !n.Diag { if !n.Diag() {
yyerror("illegal constant expression: %v %v %v", nl.Type, n.Op, nr.Type) yyerror("illegal constant expression: %v %v %v", nl.Type, n.Op, nr.Type)
n.Diag = true n.SetDiag(true)
} }
} }
...@@ -1331,9 +1331,9 @@ func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node { ...@@ -1331,9 +1331,9 @@ func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node {
if n.Val().Ctype() == CTNIL { if n.Val().Ctype() == CTNIL {
lineno = lno lineno = lno
if !n.Diag { if !n.Diag() {
yyerror("use of untyped nil") yyerror("use of untyped nil")
n.Diag = true n.SetDiag(true)
} }
n.Type = nil n.Type = nil
......
...@@ -291,7 +291,7 @@ func newname(s *Sym) *Node { ...@@ -291,7 +291,7 @@ func newname(s *Sym) *Node {
} }
n := nod(ONAME, nil, nil) n := nod(ONAME, nil, nil)
n.Sym = s n.Sym = s
n.Addable = true n.SetAddable(true)
n.Ullman = 1 n.Ullman = 1
n.Xoffset = 0 n.Xoffset = 0
return n return n
...@@ -304,7 +304,7 @@ func newnoname(s *Sym) *Node { ...@@ -304,7 +304,7 @@ func newnoname(s *Sym) *Node {
} }
n := nod(ONONAME, nil, nil) n := nod(ONONAME, nil, nil)
n.Sym = s n.Sym = s
n.Addable = true n.SetAddable(true)
n.Ullman = 1 n.Ullman = 1
n.Xoffset = 0 n.Xoffset = 0
return n return n
...@@ -315,7 +315,7 @@ func newnoname(s *Sym) *Node { ...@@ -315,7 +315,7 @@ func newnoname(s *Sym) *Node {
func newfuncname(s *Sym) *Node { func newfuncname(s *Sym) *Node {
n := newname(s) n := newname(s)
n.Func = new(Func) n.Func = new(Func)
n.Func.IsHiddenClosure = Curfn != nil n.Func.SetIsHiddenClosure(Curfn != nil)
return n return n
} }
...@@ -372,10 +372,10 @@ func oldname(s *Sym) *Node { ...@@ -372,10 +372,10 @@ func oldname(s *Sym) *Node {
c = nod(ONAME, nil, nil) c = nod(ONAME, nil, nil)
c.Sym = s c.Sym = s
c.Class = PAUTOHEAP c.Class = PAUTOHEAP
c.setIsClosureVar(true) c.SetIsClosureVar(true)
c.Isddd = n.Isddd c.SetIsddd(n.Isddd())
c.Name.Defn = n c.Name.Defn = n
c.Addable = false c.SetAddable(false)
c.Ullman = 2 c.Ullman = 2
c.Name.Funcdepth = funcdepth c.Name.Funcdepth = funcdepth
...@@ -429,7 +429,7 @@ func colasdefn(left []*Node, defn *Node) { ...@@ -429,7 +429,7 @@ func colasdefn(left []*Node, defn *Node) {
if n.Sym.Flags&SymUniq == 0 { if n.Sym.Flags&SymUniq == 0 {
yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym) yyerrorl(defn.Pos, "%v repeated on left side of :=", n.Sym)
n.Diag = true n.SetDiag(true)
nerr++ nerr++
continue continue
} }
...@@ -666,7 +666,7 @@ func structfield(n *Node) *Field { ...@@ -666,7 +666,7 @@ func structfield(n *Node) *Field {
} }
f := newField() f := newField()
f.Isddd = n.Isddd f.SetIsddd(n.Isddd())
if n.Right != nil { if n.Right != nil {
n.Right = typecheck(n.Right, Etype) n.Right = typecheck(n.Right, Etype)
...@@ -683,7 +683,7 @@ func structfield(n *Node) *Field { ...@@ -683,7 +683,7 @@ func structfield(n *Node) *Field {
f.Type = n.Type f.Type = n.Type
if f.Type == nil { if f.Type == nil {
f.Broke = true f.SetBroke(true)
} }
switch u := n.Val().U.(type) { switch u := n.Val().U.(type) {
...@@ -744,8 +744,8 @@ func tostruct0(t *Type, l []*Node) { ...@@ -744,8 +744,8 @@ func tostruct0(t *Type, l []*Node) {
fields := make([]*Field, len(l)) fields := make([]*Field, len(l))
for i, n := range l { for i, n := range l {
f := structfield(n) f := structfield(n)
if f.Broke { if f.Broke() {
t.Broke = true t.SetBroke(true)
} }
fields[i] = f fields[i] = f
} }
...@@ -753,7 +753,7 @@ func tostruct0(t *Type, l []*Node) { ...@@ -753,7 +753,7 @@ func tostruct0(t *Type, l []*Node) {
checkdupfields("field", t) checkdupfields("field", t)
if !t.Broke { if !t.Broke() {
checkwidth(t) checkwidth(t)
} }
} }
...@@ -771,8 +771,8 @@ func tofunargs(l []*Node, funarg Funarg) *Type { ...@@ -771,8 +771,8 @@ func tofunargs(l []*Node, funarg Funarg) *Type {
if n.Left != nil && n.Left.Class == PPARAM { if n.Left != nil && n.Left.Class == PPARAM {
n.Left.Name.Param.Field = f n.Left.Name.Param.Field = f
} }
if f.Broke { if f.Broke() {
t.Broke = true t.SetBroke(true)
} }
fields[i] = f fields[i] = f
} }
...@@ -809,7 +809,7 @@ func interfacefield(n *Node) *Field { ...@@ -809,7 +809,7 @@ func interfacefield(n *Node) *Field {
} }
f := newField() f := newField()
f.Isddd = n.Isddd f.SetIsddd(n.Isddd())
if n.Right != nil { if n.Right != nil {
if n.Left != nil { if n.Left != nil {
...@@ -841,11 +841,11 @@ func interfacefield(n *Node) *Field { ...@@ -841,11 +841,11 @@ func interfacefield(n *Node) *Field {
case TFORW: case TFORW:
yyerror("interface type loop involving %v", n.Type) yyerror("interface type loop involving %v", n.Type)
f.Broke = true f.SetBroke(true)
default: default:
yyerror("interface contains embedded non-interface %v", n.Type) yyerror("interface contains embedded non-interface %v", n.Type)
f.Broke = true f.SetBroke(true)
} }
} }
} }
...@@ -855,7 +855,7 @@ func interfacefield(n *Node) *Field { ...@@ -855,7 +855,7 @@ func interfacefield(n *Node) *Field {
f.Type = n.Type f.Type = n.Type
if f.Type == nil { if f.Type == nil {
f.Broke = true f.SetBroke(true)
} }
lineno = lno lineno = lno
...@@ -882,7 +882,7 @@ func tointerface0(t *Type, l []*Node) *Type { ...@@ -882,7 +882,7 @@ func tointerface0(t *Type, l []*Node) *Type {
for _, t1 := range f.Type.Fields().Slice() { for _, t1 := range f.Type.Fields().Slice() {
f = newField() f = newField()
f.Type = t1.Type f.Type = t1.Type
f.Broke = t1.Broke f.SetBroke(t1.Broke())
f.Sym = t1.Sym f.Sym = t1.Sym
if f.Sym != nil { if f.Sym != nil {
f.Nname = newname(f.Sym) f.Nname = newname(f.Sym)
...@@ -892,8 +892,8 @@ func tointerface0(t *Type, l []*Node) *Type { ...@@ -892,8 +892,8 @@ func tointerface0(t *Type, l []*Node) *Type {
} else { } else {
fields = append(fields, f) fields = append(fields, f)
} }
if f.Broke { if f.Broke() {
t.Broke = true t.SetBroke(true)
} }
} }
sort.Sort(methcmp(fields)) sort.Sort(methcmp(fields))
...@@ -980,8 +980,8 @@ func functype0(t *Type, this *Node, in, out []*Node) { ...@@ -980,8 +980,8 @@ func functype0(t *Type, this *Node, in, out []*Node) {
checkdupfields("argument", t.Recvs(), t.Results(), t.Params()) checkdupfields("argument", t.Recvs(), t.Results(), t.Params())
if t.Recvs().Broke || t.Results().Broke || t.Params().Broke { if t.Recvs().Broke() || t.Results().Broke() || t.Params().Broke() {
t.Broke = true t.SetBroke(true)
} }
t.FuncType().Outnamed = false t.FuncType().Outnamed = false
...@@ -1146,7 +1146,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) { ...@@ -1146,7 +1146,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
} }
switch { switch {
case t == nil || t.Broke: case t == nil || t.Broke():
// rely on typecheck having complained before // rely on typecheck having complained before
case t.Sym == nil: case t.Sym == nil:
yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t) yyerror("invalid receiver type %v (%v is an unnamed type)", pa, t)
...@@ -1162,7 +1162,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) { ...@@ -1162,7 +1162,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
return return
} }
if local && !mt.Local { if local && !mt.Local() {
yyerror("cannot define new methods on non-local type %v", mt) yyerror("cannot define new methods on non-local type %v", mt)
return return
} }
...@@ -1196,7 +1196,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) { ...@@ -1196,7 +1196,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
f.Sym = msym f.Sym = msym
f.Nname = newname(msym) f.Nname = newname(msym)
f.Type = t f.Type = t
f.Nointerface = nointerface f.SetNointerface(nointerface)
mt.Methods().Append(f) mt.Methods().Append(f)
} }
......
...@@ -18,7 +18,7 @@ import ( ...@@ -18,7 +18,7 @@ import (
// The algorithm (known as Tarjan's algorithm) for doing that is taken from // The algorithm (known as Tarjan's algorithm) for doing that is taken from
// Sedgewick, Algorithms, Second Edition, p. 482, with two adaptations. // Sedgewick, Algorithms, Second Edition, p. 482, with two adaptations.
// //
// First, a hidden closure function (n.Func.IsHiddenClosure) cannot be the // First, a hidden closure function (n.Func.IsHiddenClosure()) cannot be the
// root of a connected component. Refusing to use it as a root // root of a connected component. Refusing to use it as a root
// forces it into the component of the function in which it appears. // forces it into the component of the function in which it appears.
// This is more convenient for escape analysis. // This is more convenient for escape analysis.
...@@ -58,7 +58,7 @@ func visitBottomUp(list []*Node, analyze func(list []*Node, recursive bool)) { ...@@ -58,7 +58,7 @@ func visitBottomUp(list []*Node, analyze func(list []*Node, recursive bool)) {
v.analyze = analyze v.analyze = analyze
v.nodeID = make(map[*Node]uint32) v.nodeID = make(map[*Node]uint32)
for _, n := range list { for _, n := range list {
if n.Op == ODCLFUNC && !n.Func.IsHiddenClosure { if n.Op == ODCLFUNC && !n.Func.IsHiddenClosure() {
v.visit(n) v.visit(n)
} }
} }
...@@ -78,7 +78,7 @@ func (v *bottomUpVisitor) visit(n *Node) uint32 { ...@@ -78,7 +78,7 @@ func (v *bottomUpVisitor) visit(n *Node) uint32 {
v.stack = append(v.stack, n) v.stack = append(v.stack, n)
min = v.visitcodelist(n.Nbody, min) min = v.visitcodelist(n.Nbody, min)
if (min == id || min == id+1) && !n.Func.IsHiddenClosure { if (min == id || min == id+1) && !n.Func.IsHiddenClosure() {
// This node is the root of a strongly connected component. // This node is the root of a strongly connected component.
// The original min passed to visitcodelist was v.nodeID[n]+1. // The original min passed to visitcodelist was v.nodeID[n]+1.
...@@ -562,7 +562,7 @@ func (e *EscState) escfunc(fn *Node) { ...@@ -562,7 +562,7 @@ func (e *EscState) escfunc(fn *Node) {
if ln.Type != nil && !haspointers(ln.Type) { if ln.Type != nil && !haspointers(ln.Type) {
break break
} }
if Curfn.Nbody.Len() == 0 && !Curfn.Noescape { if Curfn.Nbody.Len() == 0 && !Curfn.Noescape() {
ln.Esc = EscHeap ln.Esc = EscHeap
} else { } else {
ln.Esc = EscNone // prime for escflood later ln.Esc = EscNone // prime for escflood later
...@@ -882,7 +882,7 @@ func (e *EscState) esc(n *Node, parent *Node) { ...@@ -882,7 +882,7 @@ func (e *EscState) esc(n *Node, parent *Node) {
e.escassignSinkWhy(n, n.Left, "panic") e.escassignSinkWhy(n, n.Left, "panic")
case OAPPEND: case OAPPEND:
if !n.Isddd { if !n.Isddd() {
for _, nn := range n.List.Slice()[1:] { for _, nn := range n.List.Slice()[1:] {
e.escassignSinkWhy(n, nn, "appended to slice") // lose track of assign to dereference e.escassignSinkWhy(n, nn, "appended to slice") // lose track of assign to dereference
} }
...@@ -959,7 +959,7 @@ func (e *EscState) esc(n *Node, parent *Node) { ...@@ -959,7 +959,7 @@ func (e *EscState) esc(n *Node, parent *Node) {
continue continue
} }
a := v.Name.Defn a := v.Name.Defn
if !v.Name.Byval { if !v.Name.Byval() {
a = nod(OADDR, a, nil) a = nod(OADDR, a, nil)
a.Pos = v.Pos a.Pos = v.Pos
e.nodeEscState(a).Loopdepth = e.loopdepth e.nodeEscState(a).Loopdepth = e.loopdepth
...@@ -1449,7 +1449,7 @@ func (e *EscState) initEscRetval(call *Node, fntype *Type) { ...@@ -1449,7 +1449,7 @@ func (e *EscState) initEscRetval(call *Node, fntype *Type) {
ret.Class = PAUTO ret.Class = PAUTO
ret.Name.Curfn = Curfn ret.Name.Curfn = Curfn
e.nodeEscState(ret).Loopdepth = e.loopdepth e.nodeEscState(ret).Loopdepth = e.loopdepth
ret.Used = true ret.SetUsed(true)
ret.Pos = call.Pos ret.Pos = call.Pos
cE.Retval.Append(ret) cE.Retval.Append(ret)
} }
...@@ -1550,7 +1550,7 @@ func (e *EscState) esccall(call *Node, parent *Node) { ...@@ -1550,7 +1550,7 @@ func (e *EscState) esccall(call *Node, parent *Node) {
continue continue
} }
arg := args[0] arg := args[0]
if n.Isddd && !call.Isddd { if n.Isddd() && !call.Isddd() {
// Introduce ODDDARG node to represent ... allocation. // Introduce ODDDARG node to represent ... allocation.
arg = nod(ODDDARG, nil, nil) arg = nod(ODDDARG, nil, nil)
arr := typArray(n.Type.Elem(), int64(len(args))) arr := typArray(n.Type.Elem(), int64(len(args)))
...@@ -1613,7 +1613,7 @@ func (e *EscState) esccall(call *Node, parent *Node) { ...@@ -1613,7 +1613,7 @@ func (e *EscState) esccall(call *Node, parent *Node) {
for ; i < len(args); i++ { for ; i < len(args); i++ {
arg = args[i] arg = args[i]
note = param.Note note = param.Note
if param.Isddd && !call.Isddd { if param.Isddd() && !call.Isddd() {
// Introduce ODDDARG node to represent ... allocation. // Introduce ODDDARG node to represent ... allocation.
arg = nod(ODDDARG, nil, nil) arg = nod(ODDDARG, nil, nil)
arg.Pos = call.Pos arg.Pos = call.Pos
...@@ -1637,7 +1637,7 @@ func (e *EscState) esccall(call *Node, parent *Node) { ...@@ -1637,7 +1637,7 @@ func (e *EscState) esccall(call *Node, parent *Node) {
// the function returns. // the function returns.
// This 'noescape' is even stronger than the usual esc == EscNone. // This 'noescape' is even stronger than the usual esc == EscNone.
// arg.Esc == EscNone means that arg does not escape the current function. // arg.Esc == EscNone means that arg does not escape the current function.
// arg.Noescape = true here means that arg does not escape this statement // arg.SetNoescape(true) here means that arg does not escape this statement
// in the current function. // in the current function.
case OCALLPART, case OCALLPART,
OCLOSURE, OCLOSURE,
...@@ -1646,7 +1646,7 @@ func (e *EscState) esccall(call *Node, parent *Node) { ...@@ -1646,7 +1646,7 @@ func (e *EscState) esccall(call *Node, parent *Node) {
OSLICELIT, OSLICELIT,
OPTRLIT, OPTRLIT,
OSTRUCTLIT: OSTRUCTLIT:
a.Noescape = true a.SetNoescape(true)
} }
} }
} }
...@@ -1891,7 +1891,7 @@ func (e *EscState) escwalkBody(level Level, dst *Node, src *Node, step *EscStep, ...@@ -1891,7 +1891,7 @@ func (e *EscState) escwalkBody(level Level, dst *Node, src *Node, step *EscStep,
// Treat a captured closure variable as equivalent to the // Treat a captured closure variable as equivalent to the
// original variable. // original variable.
if src.isClosureVar() { if src.IsClosureVar() {
if leaks && Debug['m'] != 0 { if leaks && Debug['m'] != 0 {
Warnl(src.Pos, "leaking closure reference %S", src) Warnl(src.Pos, "leaking closure reference %S", src)
step.describe(src) step.describe(src)
...@@ -2054,7 +2054,7 @@ func (e *EscState) esctag(fn *Node) { ...@@ -2054,7 +2054,7 @@ func (e *EscState) esctag(fn *Node) {
// External functions are assumed unsafe, // External functions are assumed unsafe,
// unless //go:noescape is given before the declaration. // unless //go:noescape is given before the declaration.
if fn.Nbody.Len() == 0 { if fn.Nbody.Len() == 0 {
if fn.Noescape { if fn.Noescape() {
for _, f := range fn.Type.Params().Fields().Slice() { for _, f := range fn.Type.Params().Fields().Slice() {
if haspointers(f.Type) { if haspointers(f.Type) {
f.Note = mktag(EscNone) f.Note = mktag(EscNone)
...@@ -2093,7 +2093,7 @@ func (e *EscState) esctag(fn *Node) { ...@@ -2093,7 +2093,7 @@ func (e *EscState) esctag(fn *Node) {
f.Note = uintptrEscapesTag f.Note = uintptrEscapesTag
} }
if f.Isddd && f.Type.Elem().Etype == TUINTPTR { if f.Isddd() && f.Type.Elem().Etype == TUINTPTR {
// final argument is ...uintptr. // final argument is ...uintptr.
if Debug['m'] != 0 { if Debug['m'] != 0 {
Warnl(fn.Pos, "%v marking %v as escaping ...uintptr", funcSym(fn), name(f.Sym, narg)) Warnl(fn.Pos, "%v marking %v as escaping ...uintptr", funcSym(fn), name(f.Sym, narg))
......
...@@ -273,8 +273,8 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) { ...@@ -273,8 +273,8 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
fmt.Fprintf(s, " u(%d)", n.Ullman) fmt.Fprintf(s, " u(%d)", n.Ullman)
} }
if c == 0 && n.Addable { if c == 0 && n.Addable() {
fmt.Fprintf(s, " a(%v)", n.Addable) fmt.Fprintf(s, " a(%v)", n.Addable())
} }
if c == 0 && n.Name != nil && n.Name.Vargen != 0 { if c == 0 && n.Name != nil && n.Name.Vargen != 0 {
...@@ -297,8 +297,8 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) { ...@@ -297,8 +297,8 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
} }
} }
if n.Colas { if n.Colas() {
fmt.Fprintf(s, " colas(%v)", n.Colas) fmt.Fprintf(s, " colas(%v)", n.Colas())
} }
if n.Name != nil && n.Name.Funcdepth != 0 { if n.Name != nil && n.Name.Funcdepth != 0 {
...@@ -335,34 +335,34 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) { ...@@ -335,34 +335,34 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
fmt.Fprintf(s, " tc(%d)", n.Typecheck) fmt.Fprintf(s, " tc(%d)", n.Typecheck)
} }
if n.Isddd { if n.Isddd() {
fmt.Fprintf(s, " isddd(%v)", n.Isddd) fmt.Fprintf(s, " isddd(%v)", n.Isddd())
} }
if n.Implicit { if n.Implicit() {
fmt.Fprintf(s, " implicit(%v)", n.Implicit) fmt.Fprintf(s, " implicit(%v)", n.Implicit())
} }
if n.Embedded != 0 { if n.Embedded != 0 {
fmt.Fprintf(s, " embedded(%d)", n.Embedded) fmt.Fprintf(s, " embedded(%d)", n.Embedded)
} }
if n.Addrtaken { if n.Addrtaken() {
fmt.Fprint(s, " addrtaken") fmt.Fprint(s, " addrtaken")
} }
if n.Assigned { if n.Assigned() {
fmt.Fprint(s, " assigned") fmt.Fprint(s, " assigned")
} }
if n.Bounded { if n.Bounded() {
fmt.Fprint(s, " bounded") fmt.Fprint(s, " bounded")
} }
if n.NonNil { if n.NonNil() {
fmt.Fprint(s, " nonnil") fmt.Fprint(s, " nonnil")
} }
if c == 0 && n.Used { if c == 0 && n.Used() {
fmt.Fprintf(s, " used(%v)", n.Used) fmt.Fprintf(s, " used(%v)", n.Used())
} }
} }
...@@ -832,14 +832,14 @@ func (n *Node) stmtfmt(s fmt.State) { ...@@ -832,14 +832,14 @@ func (n *Node) stmtfmt(s fmt.State) {
// preceded by the DCL which will be re-parsed and typechecked to reproduce // preceded by the DCL which will be re-parsed and typechecked to reproduce
// the "v = <N>" again. // the "v = <N>" again.
case OAS: case OAS:
if n.Colas && !complexinit { if n.Colas() && !complexinit {
fmt.Fprintf(s, "%v := %v", n.Left, n.Right) fmt.Fprintf(s, "%v := %v", n.Left, n.Right)
} else { } else {
fmt.Fprintf(s, "%v = %v", n.Left, n.Right) fmt.Fprintf(s, "%v = %v", n.Left, n.Right)
} }
case OASOP: case OASOP:
if n.Implicit { if n.Implicit() {
if Op(n.Etype) == OADD { if Op(n.Etype) == OADD {
fmt.Fprintf(s, "%v++", n.Left) fmt.Fprintf(s, "%v++", n.Left)
} else { } else {
...@@ -851,7 +851,7 @@ func (n *Node) stmtfmt(s fmt.State) { ...@@ -851,7 +851,7 @@ func (n *Node) stmtfmt(s fmt.State) {
fmt.Fprintf(s, "%v %#v= %v", n.Left, Op(n.Etype), n.Right) fmt.Fprintf(s, "%v %#v= %v", n.Left, Op(n.Etype), n.Right)
case OAS2: case OAS2:
if n.Colas && !complexinit { if n.Colas() && !complexinit {
fmt.Fprintf(s, "%.v := %.v", n.List, n.Rlist) fmt.Fprintf(s, "%.v := %.v", n.List, n.Rlist)
break break
} }
...@@ -1104,7 +1104,7 @@ var opprec = []int{ ...@@ -1104,7 +1104,7 @@ var opprec = []int{
} }
func (n *Node) exprfmt(s fmt.State, prec int) { func (n *Node) exprfmt(s fmt.State, prec int) {
for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) { for n != nil && n.Implicit() && (n.Op == OIND || n.Op == OADDR) {
n = n.Left n = n.Left
} }
...@@ -1224,9 +1224,9 @@ func (n *Node) exprfmt(s fmt.State, prec int) { ...@@ -1224,9 +1224,9 @@ func (n *Node) exprfmt(s fmt.State, prec int) {
fmt.Fprintf(s, "%v { %v }", n.Type, n.Func.Closure.Nbody) fmt.Fprintf(s, "%v { %v }", n.Type, n.Func.Closure.Nbody)
case OCOMPLIT: case OCOMPLIT:
ptrlit := n.Right != nil && n.Right.Implicit && n.Right.Type != nil && n.Right.Type.IsPtr() ptrlit := n.Right != nil && n.Right.Implicit() && n.Right.Type != nil && n.Right.Type.IsPtr()
if fmtmode == FErr { if fmtmode == FErr {
if n.Right != nil && n.Right.Type != nil && !n.Implicit { if n.Right != nil && n.Right.Type != nil && !n.Implicit() {
if ptrlit { if ptrlit {
fmt.Fprintf(s, "&%v literal", n.Right.Type.Elem()) fmt.Fprintf(s, "&%v literal", n.Right.Type.Elem())
return return
...@@ -1359,7 +1359,7 @@ func (n *Node) exprfmt(s fmt.State, prec int) { ...@@ -1359,7 +1359,7 @@ func (n *Node) exprfmt(s fmt.State, prec int) {
fmt.Fprintf(s, "%#v(%v)", n.Op, n.Left) fmt.Fprintf(s, "%#v(%v)", n.Op, n.Left)
return return
} }
if n.Isddd { if n.Isddd() {
fmt.Fprintf(s, "%#v(%.v...)", n.Op, n.List) fmt.Fprintf(s, "%#v(%.v...)", n.Op, n.List)
return return
} }
...@@ -1367,7 +1367,7 @@ func (n *Node) exprfmt(s fmt.State, prec int) { ...@@ -1367,7 +1367,7 @@ func (n *Node) exprfmt(s fmt.State, prec int) {
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG: case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
n.Left.exprfmt(s, nprec) n.Left.exprfmt(s, nprec)
if n.Isddd { if n.Isddd() {
fmt.Fprintf(s, "(%.v...)", n.List) fmt.Fprintf(s, "(%.v...)", n.List)
return return
} }
...@@ -1653,7 +1653,7 @@ func fldconv(f *Field, flag FmtFlag) string { ...@@ -1653,7 +1653,7 @@ func fldconv(f *Field, flag FmtFlag) string {
} }
var typ string var typ string
if f.Isddd { if f.Isddd() {
typ = fmt.Sprintf("...%v", f.Type.Elem()) typ = fmt.Sprintf("...%v", f.Type.Elem())
} else { } else {
typ = fmt.Sprintf("%v", f.Type) typ = fmt.Sprintf("%v", f.Type)
......
...@@ -38,7 +38,7 @@ func addrescapes(n *Node) { ...@@ -38,7 +38,7 @@ func addrescapes(n *Node) {
} }
// If a closure reference escapes, mark the outer variable as escaping. // If a closure reference escapes, mark the outer variable as escaping.
if n.isClosureVar() { if n.IsClosureVar() {
addrescapes(n.Name.Defn) addrescapes(n.Name.Defn)
break break
} }
...@@ -119,7 +119,7 @@ func moveToHeap(n *Node) { ...@@ -119,7 +119,7 @@ func moveToHeap(n *Node) {
// Unset AutoTemp to persist the &foo variable name through SSA to // Unset AutoTemp to persist the &foo variable name through SSA to
// liveness analysis. // liveness analysis.
// TODO(mdempsky/drchase): Cleaner solution? // TODO(mdempsky/drchase): Cleaner solution?
heapaddr.Name.AutoTemp = false heapaddr.Name.SetAutoTemp(false)
// Parameters have a local stack copy used at function start/end // Parameters have a local stack copy used at function start/end
// in addition to the copy in the heap that may live longer than // in addition to the copy in the heap that may live longer than
...@@ -145,7 +145,7 @@ func moveToHeap(n *Node) { ...@@ -145,7 +145,7 @@ func moveToHeap(n *Node) {
// Thus, we need the pointer to the heap copy always available so the // Thus, we need the pointer to the heap copy always available so the
// post-deferreturn code can copy the return value back to the stack. // post-deferreturn code can copy the return value back to the stack.
// See issue 16095. // See issue 16095.
heapaddr.setIsOutputParamHeapAddr(true) heapaddr.SetIsOutputParamHeapAddr(true)
} }
n.Name.Param.Stackcopy = stackcopy n.Name.Param.Stackcopy = stackcopy
...@@ -207,11 +207,11 @@ func tempname(nn *Node, t *Type) { ...@@ -207,11 +207,11 @@ func tempname(nn *Node, t *Type) {
s.Def = n s.Def = n
n.Type = t n.Type = t
n.Class = PAUTO n.Class = PAUTO
n.Addable = true n.SetAddable(true)
n.Ullman = 1 n.Ullman = 1
n.Esc = EscNever n.Esc = EscNever
n.Name.Curfn = Curfn n.Name.Curfn = Curfn
n.Name.AutoTemp = true n.Name.SetAutoTemp(true)
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
dowidth(t) dowidth(t)
...@@ -222,6 +222,6 @@ func tempname(nn *Node, t *Type) { ...@@ -222,6 +222,6 @@ func tempname(nn *Node, t *Type) {
func temp(t *Type) *Node { func temp(t *Type) *Node {
var n Node var n Node
tempname(&n, t) tempname(&n, t)
n.Sym.Def.Used = true n.Sym.Def.SetUsed(true)
return n.Orig return n.Orig
} }
...@@ -76,7 +76,7 @@ func ggloblnod(nam *Node) { ...@@ -76,7 +76,7 @@ func ggloblnod(nam *Node) {
s := Linksym(nam.Sym) s := Linksym(nam.Sym)
s.Gotype = Linksym(ngotype(nam)) s.Gotype = Linksym(ngotype(nam))
flags := 0 flags := 0
if nam.Name.Readonly { if nam.Name.Readonly() {
flags = obj.RODATA flags = obj.RODATA
} }
if nam.Type != nil && !haspointers(nam.Type) { if nam.Type != nil && !haspointers(nam.Type) {
...@@ -202,7 +202,7 @@ func nodarg(t interface{}, fp int) *Node { ...@@ -202,7 +202,7 @@ func nodarg(t interface{}, fp int) *Node {
Fatalf("nodarg: offset not computed for %v", t) Fatalf("nodarg: offset not computed for %v", t)
} }
n.Xoffset = first.Offset n.Xoffset = first.Offset
n.Addable = true n.SetAddable(true)
case *Field: case *Field:
funarg = t.Funarg funarg = t.Funarg
...@@ -247,7 +247,7 @@ func nodarg(t interface{}, fp int) *Node { ...@@ -247,7 +247,7 @@ func nodarg(t interface{}, fp int) *Node {
Fatalf("nodarg: offset not computed for %v", t) Fatalf("nodarg: offset not computed for %v", t)
} }
n.Xoffset = t.Offset n.Xoffset = t.Offset
n.Addable = true n.SetAddable(true)
n.Orig = t.Nname n.Orig = t.Nname
} }
...@@ -274,7 +274,7 @@ func nodarg(t interface{}, fp int) *Node { ...@@ -274,7 +274,7 @@ func nodarg(t interface{}, fp int) *Node {
} }
n.Typecheck = 1 n.Typecheck = 1
n.Addrtaken = true // keep optimizers at bay n.SetAddrtaken(true) // keep optimizers at bay
return n return n
} }
......
...@@ -130,7 +130,7 @@ func caninl(fn *Node) { ...@@ -130,7 +130,7 @@ func caninl(fn *Node) {
if Debug['l'] < 3 { if Debug['l'] < 3 {
f := fn.Type.Params().Fields() f := fn.Type.Params().Fields()
if len := f.Len(); len > 0 { if len := f.Len(); len > 0 {
if t := f.Index(len - 1); t.Isddd { if t := f.Index(len - 1); t.Isddd() {
reason = "has ... args" reason = "has ... args"
return return
} }
...@@ -403,7 +403,7 @@ func inlnode(n *Node) *Node { ...@@ -403,7 +403,7 @@ func inlnode(n *Node) *Node {
case ODEFER, OPROC: case ODEFER, OPROC:
switch n.Left.Op { switch n.Left.Op {
case OCALLFUNC, OCALLMETH: case OCALLFUNC, OCALLMETH:
n.Left.setNoInline(true) n.Left.SetNoInline(true)
} }
return n return n
...@@ -494,7 +494,7 @@ func inlnode(n *Node) *Node { ...@@ -494,7 +494,7 @@ func inlnode(n *Node) *Node {
// switch at the top of this function. // switch at the top of this function.
switch n.Op { switch n.Op {
case OCALLFUNC, OCALLMETH: case OCALLFUNC, OCALLMETH:
if n.noInline() { if n.NoInline() {
return n return n
} }
} }
...@@ -505,9 +505,9 @@ func inlnode(n *Node) *Node { ...@@ -505,9 +505,9 @@ func inlnode(n *Node) *Node {
fmt.Printf("%v:call to func %+v\n", n.Line(), n.Left) fmt.Printf("%v:call to func %+v\n", n.Line(), n.Left)
} }
if n.Left.Func != nil && n.Left.Func.Inl.Len() != 0 && !isIntrinsicCall(n) { // normal case if n.Left.Func != nil && n.Left.Func.Inl.Len() != 0 && !isIntrinsicCall(n) { // normal case
n = mkinlcall(n, n.Left, n.Isddd) n = mkinlcall(n, n.Left, n.Isddd())
} else if n.isMethodCalledAsFunction() && n.Left.Sym.Def != nil { } else if n.isMethodCalledAsFunction() && n.Left.Sym.Def != nil {
n = mkinlcall(n, n.Left.Sym.Def, n.Isddd) n = mkinlcall(n, n.Left.Sym.Def, n.Isddd())
} }
case OCALLMETH: case OCALLMETH:
...@@ -524,7 +524,7 @@ func inlnode(n *Node) *Node { ...@@ -524,7 +524,7 @@ func inlnode(n *Node) *Node {
Fatalf("no function definition for [%p] %+v\n", n.Left.Type, n.Left.Type) Fatalf("no function definition for [%p] %+v\n", n.Left.Type, n.Left.Type)
} }
n = mkinlcall(n, n.Left.Type.Nname(), n.Isddd) n = mkinlcall(n, n.Left.Type.Nname(), n.Isddd())
} }
lineno = lno lineno = lno
...@@ -671,7 +671,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { ...@@ -671,7 +671,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
var varargtype *Type var varargtype *Type
varargcount := 0 varargcount := 0
for _, t := range fn.Type.Params().Fields().Slice() { for _, t := range fn.Type.Params().Fields().Slice() {
if t.Isddd { if t.Isddd() {
variadic = true variadic = true
varargtype = t.Type varargtype = t.Type
} }
...@@ -737,7 +737,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { ...@@ -737,7 +737,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
// 0 or 1 expression on RHS. // 0 or 1 expression on RHS.
var i int var i int
for _, t := range fn.Type.Params().Fields().Slice() { for _, t := range fn.Type.Params().Fields().Slice() {
if variadic && t.Isddd { if variadic && t.Isddd() {
vararg = tinlvar(t, inlvars) vararg = tinlvar(t, inlvars)
for i = 0; i < varargcount && li < n.List.Len(); i++ { for i = 0; i < varargcount && li < n.List.Len(); i++ {
m = argvar(varargtype, i) m = argvar(varargtype, i)
...@@ -757,7 +757,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { ...@@ -757,7 +757,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
if li >= n.List.Len() { if li >= n.List.Len() {
break break
} }
if variadic && t.Isddd { if variadic && t.Isddd() {
break break
} }
as.List.Append(tinlvar(t, inlvars)) as.List.Append(tinlvar(t, inlvars))
...@@ -766,7 +766,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { ...@@ -766,7 +766,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
} }
// match varargcount arguments with variadic parameters. // match varargcount arguments with variadic parameters.
if variadic && t != nil && t.Isddd { if variadic && t != nil && t.Isddd() {
vararg = tinlvar(t, inlvars) vararg = tinlvar(t, inlvars)
var i int var i int
for i = 0; i < varargcount && li < n.List.Len(); i++ { for i = 0; i < varargcount && li < n.List.Len(); i++ {
...@@ -828,7 +828,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { ...@@ -828,7 +828,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
body := subst.list(fn.Func.Inl) body := subst.list(fn.Func.Inl)
lab := nod(OLABEL, retlabel, nil) lab := nod(OLABEL, retlabel, nil)
lab.Used = true // avoid 'not used' when function doesn't have return lab.SetUsed(true) // avoid 'not used' when function doesn't have return
body = append(body, lab) body = append(body, lab)
typecheckslice(body, Etop) typecheckslice(body, Etop)
...@@ -890,9 +890,9 @@ func inlvar(var_ *Node) *Node { ...@@ -890,9 +890,9 @@ func inlvar(var_ *Node) *Node {
n := newname(var_.Sym) n := newname(var_.Sym)
n.Type = var_.Type n.Type = var_.Type
n.Class = PAUTO n.Class = PAUTO
n.Used = true n.SetUsed(true)
n.Name.Curfn = Curfn // the calling function, not the called one n.Name.Curfn = Curfn // the calling function, not the called one
n.Addrtaken = var_.Addrtaken n.SetAddrtaken(var_.Addrtaken())
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
return n return n
...@@ -903,7 +903,7 @@ func retvar(t *Field, i int) *Node { ...@@ -903,7 +903,7 @@ func retvar(t *Field, i int) *Node {
n := newname(lookupN("~r", i)) n := newname(lookupN("~r", i))
n.Type = t.Type n.Type = t.Type
n.Class = PAUTO n.Class = PAUTO
n.Used = true n.SetUsed(true)
n.Name.Curfn = Curfn // the calling function, not the called one n.Name.Curfn = Curfn // the calling function, not the called one
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
return n return n
...@@ -915,7 +915,7 @@ func argvar(t *Type, i int) *Node { ...@@ -915,7 +915,7 @@ func argvar(t *Type, i int) *Node {
n := newname(lookupN("~arg", i)) n := newname(lookupN("~arg", i))
n.Type = t.Elem() n.Type = t.Elem()
n.Class = PAUTO n.Class = PAUTO
n.Used = true n.SetUsed(true)
n.Name.Curfn = Curfn // the calling function, not the called one n.Name.Curfn = Curfn // the calling function, not the called one
Curfn.Func.Dcl = append(Curfn.Func.Dcl, n) Curfn.Func.Dcl = append(Curfn.Func.Dcl, n)
return n return n
......
...@@ -946,7 +946,7 @@ func clearImports() { ...@@ -946,7 +946,7 @@ func clearImports() {
// leave s->block set to cause redeclaration // leave s->block set to cause redeclaration
// errors if a conflicting top-level name is // errors if a conflicting top-level name is
// introduced by a different file. // introduced by a different file.
if !s.Def.Used && nsyntaxerrors == 0 { if !s.Def.Used() && nsyntaxerrors == 0 {
pkgnotused(s.Def.Pos, s.Def.Name.Pkg.Path, s.Name) pkgnotused(s.Def.Pos, s.Def.Name.Pkg.Path, s.Name)
} }
s.Def = nil s.Def = nil
...@@ -956,9 +956,9 @@ func clearImports() { ...@@ -956,9 +956,9 @@ func clearImports() {
if s.isAlias() { if s.isAlias() {
// throw away top-level name left over // throw away top-level name left over
// from previous import . "x" // from previous import . "x"
if s.Def.Name != nil && s.Def.Name.Pack != nil && !s.Def.Name.Pack.Used && nsyntaxerrors == 0 { if s.Def.Name != nil && s.Def.Name.Pack != nil && !s.Def.Name.Pack.Used() && nsyntaxerrors == 0 {
pkgnotused(s.Def.Name.Pack.Pos, s.Def.Name.Pack.Name.Pkg.Path, "") pkgnotused(s.Def.Name.Pack.Pos, s.Def.Name.Pack.Name.Pkg.Path, "")
s.Def.Name.Pack.Used = true s.Def.Name.Pack.SetUsed(true)
} }
s.Def = nil s.Def = nil
......
...@@ -269,7 +269,7 @@ func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node { ...@@ -269,7 +269,7 @@ func (p *noder) typeDecl(decl *syntax.TypeDecl) *Node {
n := p.declName(decl.Name) n := p.declName(decl.Name)
n.Op = OTYPE n.Op = OTYPE
declare(n, dclcontext) declare(n, dclcontext)
n.Local = true n.SetLocal(true)
// decl.Type may be nil but in that case we got a syntax error during parsing // decl.Type may be nil but in that case we got a syntax error during parsing
typ := p.typeExprOrNil(decl.Type) typ := p.typeExprOrNil(decl.Type)
...@@ -317,8 +317,8 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node { ...@@ -317,8 +317,8 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
pragma := fun.Pragma pragma := fun.Pragma
f.Nbody.Set(body) f.Nbody.Set(body)
f.Noescape = pragma&Noescape != 0 f.SetNoescape(pragma&Noescape != 0)
if f.Noescape && len(body) != 0 { if f.Noescape() && len(body) != 0 {
yyerror("can only use //go:noescape with external func implementations") yyerror("can only use //go:noescape with external func implementations")
} }
f.Func.Pragma = pragma f.Func.Pragma = pragma
...@@ -404,9 +404,9 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node { ...@@ -404,9 +404,9 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
typ.Op = OTARRAY typ.Op = OTARRAY
typ.Right = typ.Left typ.Right = typ.Left
typ.Left = nil typ.Left = nil
n.Isddd = true n.SetIsddd(true)
if n.Left != nil { if n.Left != nil {
n.Left.Isddd = true n.Left.SetIsddd(true)
} }
} }
...@@ -463,7 +463,7 @@ func (p *noder) expr(expr syntax.Expr) *Node { ...@@ -463,7 +463,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
// parser.new_dotname // parser.new_dotname
obj := p.expr(expr.X) obj := p.expr(expr.X)
if obj.Op == OPACK { if obj.Op == OPACK {
obj.Used = true obj.SetUsed(true)
return oldname(restrictlookup(expr.Sel.Value, obj.Name.Pkg)) return oldname(restrictlookup(expr.Sel.Value, obj.Name.Pkg))
} }
return p.setlineno(expr, nodSym(OXDOT, obj, p.name(expr.Sel))) return p.setlineno(expr, nodSym(OXDOT, obj, p.name(expr.Sel)))
...@@ -501,7 +501,7 @@ func (p *noder) expr(expr syntax.Expr) *Node { ...@@ -501,7 +501,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
// TODO(mdempsky): Switch back to p.nod after we // TODO(mdempsky): Switch back to p.nod after we
// get rid of gcCompat. // get rid of gcCompat.
x.Right = nod(OIND, x.Right, nil) x.Right = nod(OIND, x.Right, nil)
x.Right.Implicit = true x.Right.SetImplicit(true)
return x return x
} }
} }
...@@ -511,7 +511,7 @@ func (p *noder) expr(expr syntax.Expr) *Node { ...@@ -511,7 +511,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
case *syntax.CallExpr: case *syntax.CallExpr:
n := p.nod(expr, OCALL, p.expr(expr.Fun), nil) n := p.nod(expr, OCALL, p.expr(expr.Fun), nil)
n.List.Set(p.exprs(expr.ArgList)) n.List.Set(p.exprs(expr.ArgList))
n.Isddd = expr.HasDots n.SetIsddd(expr.HasDots)
return n return n
case *syntax.ArrayType: case *syntax.ArrayType:
...@@ -625,7 +625,7 @@ func (p *noder) packname(expr syntax.Expr) *Sym { ...@@ -625,7 +625,7 @@ func (p *noder) packname(expr syntax.Expr) *Sym {
case *syntax.Name: case *syntax.Name:
name := p.name(expr) name := p.name(expr)
if n := oldname(name); n.Name != nil && n.Name.Pack != nil { if n := oldname(name); n.Name != nil && n.Name.Pack != nil {
n.Name.Pack.Used = true n.Name.Pack.SetUsed(true)
} }
return name return name
case *syntax.SelectorExpr: case *syntax.SelectorExpr:
...@@ -635,7 +635,7 @@ func (p *noder) packname(expr syntax.Expr) *Sym { ...@@ -635,7 +635,7 @@ func (p *noder) packname(expr syntax.Expr) *Sym {
yyerror("%v is not a package", name) yyerror("%v is not a package", name)
pkg = localpkg pkg = localpkg
} else { } else {
name.Def.Used = true name.Def.SetUsed(true)
pkg = name.Def.Name.Pkg pkg = name.Def.Name.Pkg
} }
return restrictlookup(expr.Sel.Value, pkg) return restrictlookup(expr.Sel.Value, pkg)
...@@ -690,7 +690,7 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node { ...@@ -690,7 +690,7 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node {
case *syntax.AssignStmt: case *syntax.AssignStmt:
if stmt.Op != 0 && stmt.Op != syntax.Def { if stmt.Op != 0 && stmt.Op != syntax.Def {
n := p.nod(stmt, OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs)) n := p.nod(stmt, OASOP, p.expr(stmt.Lhs), p.expr(stmt.Rhs))
n.Implicit = stmt.Rhs == syntax.ImplicitOne n.SetImplicit(stmt.Rhs == syntax.ImplicitOne)
n.Etype = EType(p.binOp(stmt.Op)) n.Etype = EType(p.binOp(stmt.Op))
return n return n
} }
...@@ -701,7 +701,7 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node { ...@@ -701,7 +701,7 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node {
n := p.nod(stmt, OAS, nil, nil) // assume common case n := p.nod(stmt, OAS, nil, nil) // assume common case
if stmt.Op == syntax.Def { if stmt.Op == syntax.Def {
n.Colas = true n.SetColas(true)
colasdefn(lhs, n) // modifies lhs, call before using lhs[0] in common case colasdefn(lhs, n) // modifies lhs, call before using lhs[0] in common case
} }
...@@ -836,7 +836,7 @@ func (p *noder) forStmt(stmt *syntax.ForStmt) *Node { ...@@ -836,7 +836,7 @@ func (p *noder) forStmt(stmt *syntax.ForStmt) *Node {
lhs := p.exprList(r.Lhs) lhs := p.exprList(r.Lhs)
n.List.Set(lhs) n.List.Set(lhs)
if r.Def { if r.Def {
n.Colas = true n.SetColas(true)
colasdefn(lhs, n) colasdefn(lhs, n)
} }
} }
...@@ -1074,7 +1074,7 @@ func (p *noder) wrapname(n syntax.Node, x *Node) *Node { ...@@ -1074,7 +1074,7 @@ func (p *noder) wrapname(n syntax.Node, x *Node) *Node {
fallthrough fallthrough
case ONAME, ONONAME, OPACK: case ONAME, ONONAME, OPACK:
x = p.nod(n, OPAREN, x, nil) x = p.nod(n, OPAREN, x, nil)
x.Implicit = true x.SetImplicit(true)
} }
return x return x
} }
...@@ -1147,7 +1147,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma { ...@@ -1147,7 +1147,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
func mkname(sym *Sym) *Node { func mkname(sym *Sym) *Node {
n := oldname(sym) n := oldname(sym)
if n.Name != nil && n.Name.Pack != nil { if n.Name != nil && n.Name.Pack != nil {
n.Name.Pack.Used = true n.Name.Pack.SetUsed(true)
} }
return n return n
} }
......
...@@ -191,7 +191,7 @@ func orderaddrtemp(n *Node, order *Order) *Node { ...@@ -191,7 +191,7 @@ func orderaddrtemp(n *Node, order *Order) *Node {
n = defaultlit(n, nil) n = defaultlit(n, nil)
dowidth(n.Type) dowidth(n.Type)
vstat := staticname(n.Type) vstat := staticname(n.Type)
vstat.Name.Readonly = true vstat.Name.SetReadonly(true)
var out []*Node var out []*Node
staticassign(vstat, n, &out) staticassign(vstat, n, &out)
if out != nil { if out != nil {
...@@ -239,9 +239,9 @@ func cleantempnopop(mark ordermarker, order *Order, out *[]*Node) { ...@@ -239,9 +239,9 @@ func cleantempnopop(mark ordermarker, order *Order, out *[]*Node) {
for i := len(order.temp) - 1; i >= int(mark); i-- { for i := len(order.temp) - 1; i >= int(mark); i-- {
n := order.temp[i] n := order.temp[i]
if n.Name.Keepalive { if n.Name.Keepalive() {
n.Name.Keepalive = false n.Name.SetKeepalive(false)
n.Addrtaken = true // ensure SSA keeps the n variable n.SetAddrtaken(true) // ensure SSA keeps the n variable
kill = nod(OVARLIVE, n, nil) kill = nod(OVARLIVE, n, nil)
kill = typecheck(kill, Etop) kill = typecheck(kill, Etop)
*out = append(*out, kill) *out = append(*out, kill)
...@@ -401,12 +401,12 @@ func ordercall(n *Node, order *Order) { ...@@ -401,12 +401,12 @@ func ordercall(n *Node, order *Order) {
x := *xp x := *xp
if x.Type.IsPtr() { if x.Type.IsPtr() {
x = ordercopyexpr(x, x.Type, order, 0) x = ordercopyexpr(x, x.Type, order, 0)
x.Name.Keepalive = true x.Name.SetKeepalive(true)
*xp = x *xp = x
} }
} }
next := it.Next() next := it.Next()
if next == nil && t.Isddd && t.Note == uintptrEscapesTag { if next == nil && t.Isddd() && t.Note == uintptrEscapesTag {
next = t next = t
} }
t = next t = next
...@@ -800,7 +800,7 @@ func orderstmt(n *Node, order *Order) { ...@@ -800,7 +800,7 @@ func orderstmt(n *Node, order *Order) {
// declaration (and possible allocation) until inside the case body. // declaration (and possible allocation) until inside the case body.
// Delete the ODCL nodes here and recreate them inside the body below. // Delete the ODCL nodes here and recreate them inside the body below.
case OSELRECV, OSELRECV2: case OSELRECV, OSELRECV2:
if r.Colas { if r.Colas() {
i := 0 i := 0
if r.Ninit.Len() != 0 && r.Ninit.First().Op == ODCL && r.Ninit.First().Left == r.Left { if r.Ninit.Len() != 0 && r.Ninit.First().Op == ODCL && r.Ninit.First().Left == r.Left {
i++ i++
...@@ -844,7 +844,7 @@ func orderstmt(n *Node, order *Order) { ...@@ -844,7 +844,7 @@ func orderstmt(n *Node, order *Order) {
// the conversion happens in the OAS instead. // the conversion happens in the OAS instead.
tmp1 = r.Left tmp1 = r.Left
if r.Colas { if r.Colas() {
tmp2 = nod(ODCL, tmp1, nil) tmp2 = nod(ODCL, tmp1, nil)
tmp2 = typecheck(tmp2, Etop) tmp2 = typecheck(tmp2, Etop)
n2.Ninit.Append(tmp2) n2.Ninit.Append(tmp2)
...@@ -861,7 +861,7 @@ func orderstmt(n *Node, order *Order) { ...@@ -861,7 +861,7 @@ func orderstmt(n *Node, order *Order) {
} }
if r.List.Len() != 0 { if r.List.Len() != 0 {
tmp1 = r.List.First() tmp1 = r.List.First()
if r.Colas { if r.Colas() {
tmp2 = nod(ODCL, tmp1, nil) tmp2 = nod(ODCL, tmp1, nil)
tmp2 = typecheck(tmp2, Etop) tmp2 = typecheck(tmp2, Etop)
n2.Ninit.Append(tmp2) n2.Ninit.Append(tmp2)
...@@ -1146,7 +1146,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node { ...@@ -1146,7 +1146,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node {
} }
case OCLOSURE: case OCLOSURE:
if n.Noescape && n.Func.Cvars.Len() > 0 { if n.Noescape() && n.Func.Cvars.Len() > 0 {
prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
} }
...@@ -1155,12 +1155,12 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node { ...@@ -1155,12 +1155,12 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node {
n.Right = orderexpr(n.Right, order, nil) n.Right = orderexpr(n.Right, order, nil)
orderexprlist(n.List, order) orderexprlist(n.List, order)
orderexprlist(n.Rlist, order) orderexprlist(n.Rlist, order)
if n.Noescape { if n.Noescape() {
prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
} }
case ODDDARG: case ODDDARG:
if n.Noescape { if n.Noescape() {
// The ddd argument does not live beyond the call it is created for. // The ddd argument does not live beyond the call it is created for.
// Allocate a temporary that will be cleaned up when this statement // Allocate a temporary that will be cleaned up when this statement
// completes. We could be more aggressive and try to arrange for it // completes. We could be more aggressive and try to arrange for it
......
...@@ -95,7 +95,7 @@ func gvardefx(n *Node, as obj.As) { ...@@ -95,7 +95,7 @@ func gvardefx(n *Node, as obj.As) {
switch n.Class { switch n.Class {
case PAUTO, PPARAM, PPARAMOUT: case PAUTO, PPARAM, PPARAMOUT:
if !n.Used { if !n.Used() {
Prog(obj.ANOP) Prog(obj.ANOP)
return return
} }
...@@ -187,8 +187,8 @@ func cmpstackvarlt(a, b *Node) bool { ...@@ -187,8 +187,8 @@ func cmpstackvarlt(a, b *Node) bool {
return a.Xoffset < b.Xoffset return a.Xoffset < b.Xoffset
} }
if a.Used != b.Used { if a.Used() != b.Used() {
return a.Used return a.Used()
} }
ap := haspointers(a.Type) ap := haspointers(a.Type)
...@@ -197,8 +197,8 @@ func cmpstackvarlt(a, b *Node) bool { ...@@ -197,8 +197,8 @@ func cmpstackvarlt(a, b *Node) bool {
return ap return ap
} }
ap = a.Name.Needzero ap = a.Name.Needzero()
bp = b.Name.Needzero bp = b.Name.Needzero()
if ap != bp { if ap != bp {
return ap return ap
} }
...@@ -226,13 +226,13 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) { ...@@ -226,13 +226,13 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) {
// Mark the PAUTO's unused. // Mark the PAUTO's unused.
for _, ln := range Curfn.Func.Dcl { for _, ln := range Curfn.Func.Dcl {
if ln.Class == PAUTO { if ln.Class == PAUTO {
ln.Used = false ln.SetUsed(false)
} }
} }
for _, l := range f.RegAlloc { for _, l := range f.RegAlloc {
if ls, ok := l.(ssa.LocalSlot); ok { if ls, ok := l.(ssa.LocalSlot); ok {
ls.N.(*Node).Used = true ls.N.(*Node).SetUsed(true)
} }
} }
...@@ -242,9 +242,9 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) { ...@@ -242,9 +242,9 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) {
for _, v := range b.Values { for _, v := range b.Values {
switch a := v.Aux.(type) { switch a := v.Aux.(type) {
case *ssa.ArgSymbol: case *ssa.ArgSymbol:
a.Node.(*Node).Used = true a.Node.(*Node).SetUsed(true)
case *ssa.AutoSymbol: case *ssa.AutoSymbol:
a.Node.(*Node).Used = true a.Node.(*Node).SetUsed(true)
} }
if !scratchUsed { if !scratchUsed {
...@@ -255,7 +255,7 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) { ...@@ -255,7 +255,7 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) {
if f.Config.NeedsFpScratch { if f.Config.NeedsFpScratch {
scratchFpMem = temp(Types[TUINT64]) scratchFpMem = temp(Types[TUINT64])
scratchFpMem.Used = scratchUsed scratchFpMem.SetUsed(scratchUsed)
} }
sort.Sort(byStackVar(Curfn.Func.Dcl)) sort.Sort(byStackVar(Curfn.Func.Dcl))
...@@ -265,7 +265,7 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) { ...@@ -265,7 +265,7 @@ func (s *ssaExport) AllocFrame(f *ssa.Func) {
if n.Op != ONAME || n.Class != PAUTO { if n.Op != ONAME || n.Class != PAUTO {
continue continue
} }
if !n.Used { if !n.Used() {
Curfn.Func.Dcl = Curfn.Func.Dcl[:i] Curfn.Func.Dcl = Curfn.Func.Dcl[:i]
break break
} }
...@@ -381,22 +381,22 @@ func compile(fn *Node) { ...@@ -381,22 +381,22 @@ func compile(fn *Node) {
} }
ptxt := Gins(obj.ATEXT, nam, nil) ptxt := Gins(obj.ATEXT, nam, nil)
ptxt.From3 = new(obj.Addr) ptxt.From3 = new(obj.Addr)
if fn.Func.Dupok { if fn.Func.Dupok() {
ptxt.From3.Offset |= obj.DUPOK ptxt.From3.Offset |= obj.DUPOK
} }
if fn.Func.Wrapper { if fn.Func.Wrapper() {
ptxt.From3.Offset |= obj.WRAPPER ptxt.From3.Offset |= obj.WRAPPER
} }
if fn.Func.NoFramePointer { if fn.Func.NoFramePointer() {
ptxt.From3.Offset |= obj.NOFRAME ptxt.From3.Offset |= obj.NOFRAME
} }
if fn.Func.Needctxt { if fn.Func.Needctxt() {
ptxt.From3.Offset |= obj.NEEDCTXT ptxt.From3.Offset |= obj.NEEDCTXT
} }
if fn.Func.Pragma&Nosplit != 0 { if fn.Func.Pragma&Nosplit != 0 {
ptxt.From3.Offset |= obj.NOSPLIT ptxt.From3.Offset |= obj.NOSPLIT
} }
if fn.Func.ReflectMethod { if fn.Func.ReflectMethod() {
ptxt.From3.Offset |= obj.REFLECTMETHOD ptxt.From3.Offset |= obj.REFLECTMETHOD
} }
if fn.Func.Pragma&Systemstack != 0 { if fn.Func.Pragma&Systemstack != 0 {
...@@ -449,7 +449,7 @@ func gendebug(fn *obj.LSym, decls []*Node) { ...@@ -449,7 +449,7 @@ func gendebug(fn *obj.LSym, decls []*Node) {
var name obj.AddrName var name obj.AddrName
switch n.Class { switch n.Class {
case PAUTO: case PAUTO:
if !n.Used { if !n.Used() {
continue continue
} }
name = obj.NAME_AUTO name = obj.NAME_AUTO
......
...@@ -60,13 +60,13 @@ func TestCmpstackvar(t *testing.T) { ...@@ -60,13 +60,13 @@ func TestCmpstackvar(t *testing.T) {
true, true,
}, },
{ {
Node{Class: PAUTO, Used: true}, Node{Class: PAUTO, flags: nodeUsed},
Node{Class: PAUTO, Used: false}, Node{Class: PAUTO},
true, true,
}, },
{ {
Node{Class: PAUTO, Used: false}, Node{Class: PAUTO},
Node{Class: PAUTO, Used: true}, Node{Class: PAUTO, flags: nodeUsed},
false, false,
}, },
{ {
...@@ -80,13 +80,13 @@ func TestCmpstackvar(t *testing.T) { ...@@ -80,13 +80,13 @@ func TestCmpstackvar(t *testing.T) {
true, true,
}, },
{ {
Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}}, Node{Class: PAUTO, Type: &Type{}, Name: &Name{flags: nameNeedzero}},
Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: false}}, Node{Class: PAUTO, Type: &Type{}, Name: &Name{}},
true, true,
}, },
{ {
Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: false}}, Node{Class: PAUTO, Type: &Type{}, Name: &Name{}},
Node{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}}, Node{Class: PAUTO, Type: &Type{}, Name: &Name{flags: nameNeedzero}},
false, false,
}, },
{ {
...@@ -134,10 +134,10 @@ func TestStackvarSort(t *testing.T) { ...@@ -134,10 +134,10 @@ func TestStackvarSort(t *testing.T) {
{Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Used: true, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, flags: nodeUsed, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, Type: typeWithoutPointers(), Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}, Sym: &Sym{}}, {Class: PAUTO, Type: &Type{}, Name: &Name{flags: nameNeedzero}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}}, {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{Name: "abc"}},
...@@ -148,8 +148,8 @@ func TestStackvarSort(t *testing.T) { ...@@ -148,8 +148,8 @@ func TestStackvarSort(t *testing.T) {
{Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PFUNC, Xoffset: 0, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PFUNC, Xoffset: 10, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PFUNC, Xoffset: 20, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Used: true, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, flags: nodeUsed, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{Needzero: true}, Sym: &Sym{}}, {Class: PAUTO, Type: &Type{}, Name: &Name{flags: nameNeedzero}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, Type: &Type{Width: 2}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, Type: &Type{Width: 1}, Name: &Name{}, Sym: &Sym{}},
{Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}}, {Class: PAUTO, Type: &Type{}, Name: &Name{}, Sym: &Sym{}},
......
...@@ -569,7 +569,7 @@ func (lv *Liveness) initcache() { ...@@ -569,7 +569,7 @@ func (lv *Liveness) initcache() {
// function runs. // function runs.
lv.cache.tailuevar = append(lv.cache.tailuevar, int32(i)) lv.cache.tailuevar = append(lv.cache.tailuevar, int32(i))
if node.Addrtaken { if node.Addrtaken() {
lv.cache.textavarinit = append(lv.cache.textavarinit, int32(i)) lv.cache.textavarinit = append(lv.cache.textavarinit, int32(i))
} }
lv.cache.textvarkill = append(lv.cache.textvarkill, int32(i)) lv.cache.textvarkill = append(lv.cache.textvarkill, int32(i))
...@@ -582,7 +582,7 @@ func (lv *Liveness) initcache() { ...@@ -582,7 +582,7 @@ func (lv *Liveness) initcache() {
// So only use uevar in the non-addrtaken case. // So only use uevar in the non-addrtaken case.
// The p.to.type == obj.TYPE_NONE limits the bvset to // The p.to.type == obj.TYPE_NONE limits the bvset to
// non-tail-call return instructions; see note below for details. // non-tail-call return instructions; see note below for details.
if !node.Addrtaken { if !node.Addrtaken() {
lv.cache.retuevar = append(lv.cache.retuevar, int32(i)) lv.cache.retuevar = append(lv.cache.retuevar, int32(i))
} }
} }
...@@ -645,7 +645,7 @@ func (lv *Liveness) progeffects(prog *obj.Prog) (uevar, varkill, avarinit []int3 ...@@ -645,7 +645,7 @@ func (lv *Liveness) progeffects(prog *obj.Prog) (uevar, varkill, avarinit []int3
if from.Node != nil && from.Sym != nil { if from.Node != nil && from.Sym != nil {
n := from.Node.(*Node) n := from.Node.(*Node)
if pos := liveIndex(n, lv.vars); pos >= 0 { if pos := liveIndex(n, lv.vars); pos >= 0 {
if n.Addrtaken { if n.Addrtaken() {
avarinit = append(avarinit, pos) avarinit = append(avarinit, pos)
} else { } else {
if info.Flags&(LeftRead|LeftAddr) != 0 { if info.Flags&(LeftRead|LeftAddr) != 0 {
...@@ -664,7 +664,7 @@ func (lv *Liveness) progeffects(prog *obj.Prog) (uevar, varkill, avarinit []int3 ...@@ -664,7 +664,7 @@ func (lv *Liveness) progeffects(prog *obj.Prog) (uevar, varkill, avarinit []int3
if from.Node != nil && from.Sym != nil { if from.Node != nil && from.Sym != nil {
n := from.Node.(*Node) n := from.Node.(*Node)
if pos := liveIndex(n, lv.vars); pos >= 0 { if pos := liveIndex(n, lv.vars); pos >= 0 {
if n.Addrtaken { if n.Addrtaken() {
avarinit = append(avarinit, pos) avarinit = append(avarinit, pos)
} else { } else {
uevar = append(uevar, pos) uevar = append(uevar, pos)
...@@ -678,7 +678,7 @@ func (lv *Liveness) progeffects(prog *obj.Prog) (uevar, varkill, avarinit []int3 ...@@ -678,7 +678,7 @@ func (lv *Liveness) progeffects(prog *obj.Prog) (uevar, varkill, avarinit []int3
if to.Node != nil && to.Sym != nil { if to.Node != nil && to.Sym != nil {
n := to.Node.(*Node) n := to.Node.(*Node)
if pos := liveIndex(n, lv.vars); pos >= 0 { if pos := liveIndex(n, lv.vars); pos >= 0 {
if n.Addrtaken { if n.Addrtaken() {
if prog.As != obj.AVARKILL { if prog.As != obj.AVARKILL {
avarinit = append(avarinit, pos) avarinit = append(avarinit, pos)
} }
...@@ -770,7 +770,7 @@ func printnode(node *Node) { ...@@ -770,7 +770,7 @@ func printnode(node *Node) {
p = "^" p = "^"
} }
a := "" a := ""
if node.Addrtaken { if node.Addrtaken() {
a = "@" a = "@"
} }
fmt.Printf(" %v%s%s", node, p, a) fmt.Printf(" %v%s%s", node, p, a)
...@@ -1223,7 +1223,7 @@ func livenessepilogue(lv *Liveness) { ...@@ -1223,7 +1223,7 @@ func livenessepilogue(lv *Liveness) {
livedefer.Set(int32(i)) livedefer.Set(int32(i))
} }
if n.IsOutputParamHeapAddr() { if n.IsOutputParamHeapAddr() {
n.Name.Needzero = true n.Name.SetNeedzero(true)
livedefer.Set(int32(i)) livedefer.Set(int32(i))
} }
} }
...@@ -1274,8 +1274,8 @@ func livenessepilogue(lv *Liveness) { ...@@ -1274,8 +1274,8 @@ func livenessepilogue(lv *Liveness) {
} }
all.Set(pos) // silence future warnings in this block all.Set(pos) // silence future warnings in this block
n := lv.vars[pos] n := lv.vars[pos]
if !n.Name.Needzero { if !n.Name.Needzero() {
n.Name.Needzero = true n.Name.SetNeedzero(true)
if debuglive >= 1 { if debuglive >= 1 {
Warnl(p.Pos, "%v: %L is ambiguously live", Curfn.Func.Nname, n) Warnl(p.Pos, "%v: %L is ambiguously live", Curfn.Func.Nname, n)
} }
......
...@@ -563,7 +563,7 @@ func makeaddable(n *Node) { ...@@ -563,7 +563,7 @@ func makeaddable(n *Node) {
func uintptraddr(n *Node) *Node { func uintptraddr(n *Node) *Node {
r := nod(OADDR, n, nil) r := nod(OADDR, n, nil)
r.Bounded = true r.SetBounded(true)
r = conv(r, Types[TUNSAFEPTR]) r = conv(r, Types[TUNSAFEPTR])
r = conv(r, Types[TUINTPTR]) r = conv(r, Types[TUINTPTR])
return r return r
......
...@@ -188,7 +188,7 @@ func walkrange(n *Node) { ...@@ -188,7 +188,7 @@ func walkrange(n *Node) {
if v2 != nil { if v2 != nil {
hp = temp(ptrto(n.Type.Elem())) hp = temp(ptrto(n.Type.Elem()))
tmp := nod(OINDEX, ha, nodintconst(0)) tmp := nod(OINDEX, ha, nodintconst(0))
tmp.Bounded = true tmp.SetBounded(true)
init = append(init, nod(OAS, hp, nod(OADDR, tmp, nil))) init = append(init, nod(OAS, hp, nod(OADDR, tmp, nil)))
} }
...@@ -325,7 +325,7 @@ func walkrange(n *Node) { ...@@ -325,7 +325,7 @@ func walkrange(n *Node) {
// hv2 := rune(ha[hv1]) // hv2 := rune(ha[hv1])
nind := nod(OINDEX, ha, hv1) nind := nod(OINDEX, ha, hv1)
nind.Bounded = true nind.SetBounded(true)
body = append(body, nod(OAS, hv2, conv(nind, runetype))) body = append(body, nod(OAS, hv2, conv(nind, runetype)))
// if hv2 < utf8.RuneSelf // if hv2 < utf8.RuneSelf
...@@ -422,7 +422,7 @@ func memclrrange(n, v1, v2, a *Node) bool { ...@@ -422,7 +422,7 @@ func memclrrange(n, v1, v2, a *Node) bool {
hp := temp(Types[TUNSAFEPTR]) hp := temp(Types[TUNSAFEPTR])
tmp := nod(OINDEX, a, nodintconst(0)) tmp := nod(OINDEX, a, nodintconst(0))
tmp.Bounded = true tmp.SetBounded(true)
tmp = nod(OADDR, tmp, nil) tmp = nod(OADDR, tmp, nil)
tmp = nod(OCONVNOP, tmp, nil) tmp = nod(OCONVNOP, tmp, nil)
tmp.Type = Types[TUNSAFEPTR] tmp.Type = Types[TUNSAFEPTR]
......
...@@ -115,11 +115,11 @@ func mapbucket(t *Type) *Type { ...@@ -115,11 +115,11 @@ func mapbucket(t *Type) *Type {
field = append(field, makefield("topbits", arr)) field = append(field, makefield("topbits", arr))
arr = typArray(keytype, BUCKETSIZE) arr = typArray(keytype, BUCKETSIZE)
arr.Noalg = true arr.SetNoalg(true)
field = append(field, makefield("keys", arr)) field = append(field, makefield("keys", arr))
arr = typArray(valtype, BUCKETSIZE) arr = typArray(valtype, BUCKETSIZE)
arr.Noalg = true arr.SetNoalg(true)
field = append(field, makefield("values", arr)) field = append(field, makefield("values", arr))
// Make sure the overflow pointer is the last memory in the struct, // Make sure the overflow pointer is the last memory in the struct,
...@@ -157,8 +157,8 @@ func mapbucket(t *Type) *Type { ...@@ -157,8 +157,8 @@ func mapbucket(t *Type) *Type {
field = append(field, ovf) field = append(field, ovf)
// link up fields // link up fields
bucket.Noalg = true bucket.SetNoalg(true)
bucket.Local = t.Local bucket.SetLocal(t.Local())
bucket.SetFields(field[:]) bucket.SetFields(field[:])
dowidth(bucket) dowidth(bucket)
...@@ -195,8 +195,8 @@ func hmap(t *Type) *Type { ...@@ -195,8 +195,8 @@ func hmap(t *Type) *Type {
} }
h := typ(TSTRUCT) h := typ(TSTRUCT)
h.Noalg = true h.SetNoalg(true)
h.Local = t.Local h.SetLocal(t.Local())
h.SetFields(fields) h.SetFields(fields)
dowidth(h) dowidth(h)
t.MapType().Hmap = h t.MapType().Hmap = h
...@@ -241,7 +241,7 @@ func hiter(t *Type) *Type { ...@@ -241,7 +241,7 @@ func hiter(t *Type) *Type {
// build iterator struct holding the above fields // build iterator struct holding the above fields
i := typ(TSTRUCT) i := typ(TSTRUCT)
i.Noalg = true i.SetNoalg(true)
i.SetFields(field[:]) i.SetFields(field[:])
dowidth(i) dowidth(i)
if i.Width != int64(12*Widthptr) { if i.Width != int64(12*Widthptr) {
...@@ -266,7 +266,7 @@ func methodfunc(f *Type, receiver *Type) *Type { ...@@ -266,7 +266,7 @@ func methodfunc(f *Type, receiver *Type) *Type {
for _, t := range f.Params().Fields().Slice() { for _, t := range f.Params().Fields().Slice() {
d = nod(ODCLFIELD, nil, nil) d = nod(ODCLFIELD, nil, nil)
d.Type = t.Type d.Type = t.Type
d.Isddd = t.Isddd d.SetIsddd(t.Isddd())
in = append(in, d) in = append(in, d)
} }
...@@ -314,7 +314,7 @@ func methods(t *Type) []*Sig { ...@@ -314,7 +314,7 @@ func methods(t *Type) []*Sig {
if f.Type.Recv() == nil { if f.Type.Recv() == nil {
Fatalf("receiver with no type on %v method %v %v\n", mt, f.Sym, f) Fatalf("receiver with no type on %v method %v %v\n", mt, f.Sym, f)
} }
if f.Nointerface { if f.Nointerface() {
continue continue
} }
...@@ -943,7 +943,7 @@ func typesym(t *Type) *Sym { ...@@ -943,7 +943,7 @@ func typesym(t *Type) *Sym {
name := t.tconv(FmtLeft) name := t.tconv(FmtLeft)
// Use a separate symbol name for Noalg types for #17752. // Use a separate symbol name for Noalg types for #17752.
if a, bad := algtype1(t); a == ANOEQ && bad.Noalg { if a, bad := algtype1(t); a == ANOEQ && bad.Noalg() {
name = "noalg." + name name = "noalg." + name
} }
...@@ -987,7 +987,7 @@ func typename(t *Type) *Node { ...@@ -987,7 +987,7 @@ func typename(t *Type) *Node {
s := typenamesym(t) s := typenamesym(t)
n := nod(OADDR, s.Def, nil) n := nod(OADDR, s.Def, nil)
n.Type = ptrto(s.Def.Type) n.Type = ptrto(s.Def.Type)
n.Addable = true n.SetAddable(true)
n.Ullman = 2 n.Ullman = 2
n.Typecheck = 1 n.Typecheck = 1
return n return n
...@@ -1010,7 +1010,7 @@ func itabname(t, itype *Type) *Node { ...@@ -1010,7 +1010,7 @@ func itabname(t, itype *Type) *Node {
n := nod(OADDR, s.Def, nil) n := nod(OADDR, s.Def, nil)
n.Type = ptrto(s.Def.Type) n.Type = ptrto(s.Def.Type)
n.Addable = true n.SetAddable(true)
n.Ullman = 2 n.Ullman = 2
n.Typecheck = 1 n.Typecheck = 1
return n return n
...@@ -1146,7 +1146,7 @@ func dtypesym(t *Type) *Sym { ...@@ -1146,7 +1146,7 @@ func dtypesym(t *Type) *Sym {
} }
// named types from other files are defined only by those files // named types from other files are defined only by those files
if tbase.Sym != nil && !tbase.Local { if tbase.Sym != nil && !tbase.Local() {
return s return s
} }
if isforw[tbase.Etype] { if isforw[tbase.Etype] {
...@@ -1192,7 +1192,7 @@ ok: ...@@ -1192,7 +1192,7 @@ ok:
} }
isddd := false isddd := false
for _, t1 := range t.Params().Fields().Slice() { for _, t1 := range t.Params().Fields().Slice() {
isddd = t1.Isddd isddd = t1.Isddd()
dtypesym(t1.Type) dtypesym(t1.Type)
} }
for _, t1 := range t.Results().Fields().Slice() { for _, t1 := range t.Results().Fields().Slice() {
...@@ -1789,7 +1789,7 @@ func zeroaddr(size int64) *Node { ...@@ -1789,7 +1789,7 @@ func zeroaddr(size int64) *Node {
} }
z := nod(OADDR, s.Def, nil) z := nod(OADDR, s.Def, nil)
z.Type = ptrto(Types[TUINT8]) z.Type = ptrto(Types[TUINT8])
z.Addable = true z.SetAddable(true)
z.Typecheck = 1 z.Typecheck = 1
return z return z
} }
...@@ -44,7 +44,7 @@ func typecheckselect(sel *Node) { ...@@ -44,7 +44,7 @@ func typecheckselect(sel *Node) {
// remove implicit conversions; the eventual assignment // remove implicit conversions; the eventual assignment
// will reintroduce them. // will reintroduce them.
case OAS: case OAS:
if (n.Right.Op == OCONVNOP || n.Right.Op == OCONVIFACE) && n.Right.Implicit { if (n.Right.Op == OCONVNOP || n.Right.Op == OCONVIFACE) && n.Right.Implicit() {
n.Right = n.Right.Left n.Right = n.Right.Left
} }
...@@ -332,8 +332,8 @@ func selecttype(size int32) *Type { ...@@ -332,8 +332,8 @@ func selecttype(size int32) *Type {
scase.List.Append(nod(ODCLFIELD, newname(lookup("receivedp")), typenod(ptrto(Types[TUINT8])))) scase.List.Append(nod(ODCLFIELD, newname(lookup("receivedp")), typenod(ptrto(Types[TUINT8]))))
scase.List.Append(nod(ODCLFIELD, newname(lookup("releasetime")), typenod(Types[TUINT64]))) scase.List.Append(nod(ODCLFIELD, newname(lookup("releasetime")), typenod(Types[TUINT64])))
scase = typecheck(scase, Etype) scase = typecheck(scase, Etype)
scase.Type.Noalg = true scase.Type.SetNoalg(true)
scase.Type.Local = true scase.Type.SetLocal(true)
sel := nod(OTSTRUCT, nil, nil) sel := nod(OTSTRUCT, nil, nil)
sel.List.Append(nod(ODCLFIELD, newname(lookup("tcase")), typenod(Types[TUINT16]))) sel.List.Append(nod(ODCLFIELD, newname(lookup("tcase")), typenod(Types[TUINT16])))
...@@ -347,8 +347,8 @@ func selecttype(size int32) *Type { ...@@ -347,8 +347,8 @@ func selecttype(size int32) *Type {
arr = nod(OTARRAY, nodintconst(int64(size)), typenod(Types[TUINT16])) arr = nod(OTARRAY, nodintconst(int64(size)), typenod(Types[TUINT16]))
sel.List.Append(nod(ODCLFIELD, newname(lookup("pollorderarr")), arr)) sel.List.Append(nod(ODCLFIELD, newname(lookup("pollorderarr")), arr))
sel = typecheck(sel, Etype) sel = typecheck(sel, Etype)
sel.Type.Noalg = true sel.Type.SetNoalg(true)
sel.Type.Local = true sel.Type.SetLocal(true)
return sel.Type return sel.Type
} }
...@@ -570,7 +570,7 @@ const ( ...@@ -570,7 +570,7 @@ const (
// part of the composite literal. // part of the composite literal.
// staticname returns a name backed by a static data symbol. // staticname returns a name backed by a static data symbol.
// Callers should set n.Name.Readonly = true on the // Callers should call n.Name.SetReadonly(true) on the
// returned node for readonly nodes. // returned node for readonly nodes.
func staticname(t *Type) *Node { func staticname(t *Type) *Node {
n := newname(lookupN("statictmp_", statuniqgen)) n := newname(lookupN("statictmp_", statuniqgen))
...@@ -585,7 +585,7 @@ func isliteral(n *Node) bool { ...@@ -585,7 +585,7 @@ func isliteral(n *Node) bool {
} }
func (n *Node) isSimpleName() bool { func (n *Node) isSimpleName() bool {
return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP && n.Class != PEXTERN return n.Op == ONAME && n.Addable() && n.Class != PAUTOHEAP && n.Class != PEXTERN
} }
func litas(l *Node, r *Node, init *Nodes) { func litas(l *Node, r *Node, init *Nodes) {
...@@ -822,7 +822,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { ...@@ -822,7 +822,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
if mode&initConst != 0 { if mode&initConst != 0 {
vstat = staticname(t) vstat = staticname(t)
if ctxt == inInitFunction { if ctxt == inInitFunction {
vstat.Name.Readonly = true vstat.Name.SetReadonly(true)
} }
fixedlit(ctxt, initKindStatic, n, vstat, init) fixedlit(ctxt, initKindStatic, n, vstat, init)
} }
...@@ -882,7 +882,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { ...@@ -882,7 +882,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
value = r.Right value = r.Right
} }
a := nod(OINDEX, vauto, nodintconst(index)) a := nod(OINDEX, vauto, nodintconst(index))
a.Bounded = true a.SetBounded(true)
index++ index++
// TODO need to check bounds? // TODO need to check bounds?
...@@ -952,9 +952,9 @@ func maplit(n *Node, m *Node, init *Nodes) { ...@@ -952,9 +952,9 @@ func maplit(n *Node, m *Node, init *Nodes) {
// make and initialize static arrays // make and initialize static arrays
vstatk := staticname(tk) vstatk := staticname(tk)
vstatk.Name.Readonly = true vstatk.Name.SetReadonly(true)
vstatv := staticname(tv) vstatv := staticname(tv)
vstatv.Name.Readonly = true vstatv.Name.SetReadonly(true)
b := int64(0) b := int64(0)
for _, r := range n.List.Slice() { for _, r := range n.List.Slice() {
...@@ -989,10 +989,10 @@ func maplit(n *Node, m *Node, init *Nodes) { ...@@ -989,10 +989,10 @@ func maplit(n *Node, m *Node, init *Nodes) {
// } // }
i := temp(Types[TINT]) i := temp(Types[TINT])
rhs := nod(OINDEX, vstatv, i) rhs := nod(OINDEX, vstatv, i)
rhs.Bounded = true rhs.SetBounded(true)
kidx := nod(OINDEX, vstatk, i) kidx := nod(OINDEX, vstatk, i)
kidx.Bounded = true kidx.SetBounded(true)
lhs := nod(OINDEX, m, kidx) lhs := nod(OINDEX, m, kidx)
zero := nod(OAS, i, nodintconst(0)) zero := nod(OAS, i, nodintconst(0))
...@@ -1104,7 +1104,7 @@ func anylit(n *Node, var_ *Node, init *Nodes) { ...@@ -1104,7 +1104,7 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
if var_.isSimpleName() && n.List.Len() > 4 { if var_.isSimpleName() && n.List.Len() > 4 {
// lay out static data // lay out static data
vstat := staticname(t) vstat := staticname(t)
vstat.Name.Readonly = true vstat.Name.SetReadonly(true)
ctxt := inInitFunction ctxt := inInitFunction
if n.Op == OARRAYLIT { if n.Op == OARRAYLIT {
...@@ -1203,7 +1203,7 @@ func stataddr(nam *Node, n *Node) bool { ...@@ -1203,7 +1203,7 @@ func stataddr(nam *Node, n *Node) bool {
switch n.Op { switch n.Op {
case ONAME: case ONAME:
*nam = *n *nam = *n
return n.Addable return n.Addable()
case ODOT: case ODOT:
if !stataddr(nam, n.Left) { if !stataddr(nam, n.Left) {
......
...@@ -22,12 +22,12 @@ func TestSizeof(t *testing.T) { ...@@ -22,12 +22,12 @@ func TestSizeof(t *testing.T) {
_32bit uintptr // size on 32bit platforms _32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms _64bit uintptr // size on 64bit platforms
}{ }{
{Func{}, 100, 168}, {Func{}, 96, 160},
{Name{}, 40, 64}, {Name{}, 36, 56},
{Param{}, 28, 56}, {Param{}, 28, 56},
{Node{}, 96, 152}, {Node{}, 84, 136},
{Sym{}, 64, 120}, {Sym{}, 64, 120},
{Type{}, 64, 104}, {Type{}, 60, 96},
{MapType{}, 20, 40}, {MapType{}, 20, 40},
{ForwardType{}, 20, 32}, {ForwardType{}, 20, 32},
{FuncType{}, 28, 48}, {FuncType{}, 28, 48},
......
...@@ -140,7 +140,7 @@ func buildssa(fn *Node) *ssa.Func { ...@@ -140,7 +140,7 @@ func buildssa(fn *Node) *ssa.Func {
// Check that we used all labels // Check that we used all labels
for name, lab := range s.labels { for name, lab := range s.labels {
if !lab.used() && !lab.reported && !lab.defNode.Used { if !lab.used() && !lab.reported && !lab.defNode.Used() {
yyerrorl(lab.defNode.Pos, "label %v defined and not used", name) yyerrorl(lab.defNode.Pos, "label %v defined and not used", name)
lab.reported = true lab.reported = true
} }
...@@ -930,7 +930,7 @@ func (s *state) stmt(n *Node) { ...@@ -930,7 +930,7 @@ func (s *state) stmt(n *Node) {
case OVARLIVE: case OVARLIVE:
// Insert a varlive op to record that a variable is still live. // Insert a varlive op to record that a variable is still live.
if !n.Left.Addrtaken { if !n.Left.Addrtaken() {
s.Fatalf("VARLIVE variable %v must have Addrtaken set", n.Left) s.Fatalf("VARLIVE variable %v must have Addrtaken set", n.Left)
} }
s.vars[&memVar] = s.newValue1A(ssa.OpVarLive, ssa.TypeMem, n.Left, s.mem()) s.vars[&memVar] = s.newValue1A(ssa.OpVarLive, ssa.TypeMem, n.Left, s.mem())
...@@ -1919,7 +1919,7 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -1919,7 +1919,7 @@ func (s *state) expr(n *Node) *ssa.Value {
return s.expr(n.Left) return s.expr(n.Left)
case OADDR: case OADDR:
return s.addr(n.Left, n.Bounded) return s.addr(n.Left, n.Bounded())
case OINDREGSP: case OINDREGSP:
addr := s.entryNewValue1I(ssa.OpOffPtr, ptrto(n.Type), n.Xoffset, s.sp) addr := s.entryNewValue1I(ssa.OpOffPtr, ptrto(n.Type), n.Xoffset, s.sp)
...@@ -1955,7 +1955,7 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -1955,7 +1955,7 @@ func (s *state) expr(n *Node) *ssa.Value {
case OINDEX: case OINDEX:
switch { switch {
case n.Left.Type.IsString(): case n.Left.Type.IsString():
if n.Bounded && Isconst(n.Left, CTSTR) && Isconst(n.Right, CTINT) { if n.Bounded() && Isconst(n.Left, CTSTR) && Isconst(n.Right, CTINT) {
// Replace "abc"[1] with 'b'. // Replace "abc"[1] with 'b'.
// Delayed until now because "abc"[1] is not an ideal constant. // Delayed until now because "abc"[1] is not an ideal constant.
// See test/fixedbugs/issue11370.go. // See test/fixedbugs/issue11370.go.
...@@ -1964,7 +1964,7 @@ func (s *state) expr(n *Node) *ssa.Value { ...@@ -1964,7 +1964,7 @@ func (s *state) expr(n *Node) *ssa.Value {
a := s.expr(n.Left) a := s.expr(n.Left)
i := s.expr(n.Right) i := s.expr(n.Right)
i = s.extendIndex(i, panicindex) i = s.extendIndex(i, panicindex)
if !n.Bounded { if !n.Bounded() {
len := s.newValue1(ssa.OpStringLen, Types[TINT], a) len := s.newValue1(ssa.OpStringLen, Types[TINT], a)
s.boundsCheck(i, len) s.boundsCheck(i, len)
} }
...@@ -3105,7 +3105,7 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value { ...@@ -3105,7 +3105,7 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
i := s.expr(n.Right) i := s.expr(n.Right)
i = s.extendIndex(i, panicindex) i = s.extendIndex(i, panicindex)
len := s.newValue1(ssa.OpSliceLen, Types[TINT], a) len := s.newValue1(ssa.OpSliceLen, Types[TINT], a)
if !n.Bounded { if !n.Bounded() {
s.boundsCheck(i, len) s.boundsCheck(i, len)
} }
p := s.newValue1(ssa.OpSlicePtr, t, a) p := s.newValue1(ssa.OpSlicePtr, t, a)
...@@ -3115,7 +3115,7 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value { ...@@ -3115,7 +3115,7 @@ func (s *state) addr(n *Node, bounded bool) *ssa.Value {
i := s.expr(n.Right) i := s.expr(n.Right)
i = s.extendIndex(i, panicindex) i = s.extendIndex(i, panicindex)
len := s.constInt(Types[TINT], n.Left.Type.NumElem()) len := s.constInt(Types[TINT], n.Left.Type.NumElem())
if !n.Bounded { if !n.Bounded() {
s.boundsCheck(i, len) s.boundsCheck(i, len)
} }
return s.newValue2(ssa.OpPtrIndex, ptrto(n.Left.Type.Elem()), a, i) return s.newValue2(ssa.OpPtrIndex, ptrto(n.Left.Type.Elem()), a, i)
...@@ -3163,7 +3163,7 @@ func (s *state) canSSA(n *Node) bool { ...@@ -3163,7 +3163,7 @@ func (s *state) canSSA(n *Node) bool {
if n.Op != ONAME { if n.Op != ONAME {
return false return false
} }
if n.Addrtaken { if n.Addrtaken() {
return false return false
} }
if n.isParamHeapCopy() { if n.isParamHeapCopy() {
...@@ -3239,7 +3239,7 @@ func canSSAType(t *Type) bool { ...@@ -3239,7 +3239,7 @@ func canSSAType(t *Type) bool {
// exprPtr evaluates n to a pointer and nil-checks it. // exprPtr evaluates n to a pointer and nil-checks it.
func (s *state) exprPtr(n *Node, bounded bool, lineno src.XPos) *ssa.Value { func (s *state) exprPtr(n *Node, bounded bool, lineno src.XPos) *ssa.Value {
p := s.expr(n) p := s.expr(n)
if bounded || n.NonNil { if bounded || n.NonNil() {
if s.f.Config.Debug_checknil() && lineno.Line() > 1 { if s.f.Config.Debug_checknil() && lineno.Line() > 1 {
s.f.Config.Warnl(lineno, "removed nil check") s.f.Config.Warnl(lineno, "removed nil check")
} }
...@@ -4761,7 +4761,7 @@ func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlo ...@@ -4761,7 +4761,7 @@ func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlo
n := name.N.(*Node) n := name.N.(*Node)
ptrType := ptrto(Types[TUINT8]) ptrType := ptrto(Types[TUINT8])
lenType := Types[TINT] lenType := Types[TINT]
if n.Class == PAUTO && !n.Addrtaken { if n.Class == PAUTO && !n.Addrtaken() {
// Split this string up into two separate variables. // Split this string up into two separate variables.
p := e.namedAuto(n.Sym.Name+".ptr", ptrType) p := e.namedAuto(n.Sym.Name+".ptr", ptrType)
l := e.namedAuto(n.Sym.Name+".len", lenType) l := e.namedAuto(n.Sym.Name+".len", lenType)
...@@ -4774,7 +4774,7 @@ func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlo ...@@ -4774,7 +4774,7 @@ func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlo
func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) { func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
n := name.N.(*Node) n := name.N.(*Node)
t := ptrto(Types[TUINT8]) t := ptrto(Types[TUINT8])
if n.Class == PAUTO && !n.Addrtaken { if n.Class == PAUTO && !n.Addrtaken() {
// Split this interface up into two separate variables. // Split this interface up into two separate variables.
f := ".itab" f := ".itab"
if n.Type.IsEmptyInterface() { if n.Type.IsEmptyInterface() {
...@@ -4792,7 +4792,7 @@ func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot ...@@ -4792,7 +4792,7 @@ func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
n := name.N.(*Node) n := name.N.(*Node)
ptrType := ptrto(name.Type.ElemType().(*Type)) ptrType := ptrto(name.Type.ElemType().(*Type))
lenType := Types[TINT] lenType := Types[TINT]
if n.Class == PAUTO && !n.Addrtaken { if n.Class == PAUTO && !n.Addrtaken() {
// Split this slice up into three separate variables. // Split this slice up into three separate variables.
p := e.namedAuto(n.Sym.Name+".ptr", ptrType) p := e.namedAuto(n.Sym.Name+".ptr", ptrType)
l := e.namedAuto(n.Sym.Name+".len", lenType) l := e.namedAuto(n.Sym.Name+".len", lenType)
...@@ -4814,7 +4814,7 @@ func (e *ssaExport) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSl ...@@ -4814,7 +4814,7 @@ func (e *ssaExport) SplitComplex(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSl
} else { } else {
t = Types[TFLOAT32] t = Types[TFLOAT32]
} }
if n.Class == PAUTO && !n.Addrtaken { if n.Class == PAUTO && !n.Addrtaken() {
// Split this complex up into two separate variables. // Split this complex up into two separate variables.
c := e.namedAuto(n.Sym.Name+".real", t) c := e.namedAuto(n.Sym.Name+".real", t)
d := e.namedAuto(n.Sym.Name+".imag", t) d := e.namedAuto(n.Sym.Name+".imag", t)
...@@ -4832,7 +4832,7 @@ func (e *ssaExport) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot ...@@ -4832,7 +4832,7 @@ func (e *ssaExport) SplitInt64(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot
} else { } else {
t = Types[TUINT32] t = Types[TUINT32]
} }
if n.Class == PAUTO && !n.Addrtaken { if n.Class == PAUTO && !n.Addrtaken() {
// Split this int64 up into two separate variables. // Split this int64 up into two separate variables.
h := e.namedAuto(n.Sym.Name+".hi", t) h := e.namedAuto(n.Sym.Name+".hi", t)
l := e.namedAuto(n.Sym.Name+".lo", Types[TUINT32]) l := e.namedAuto(n.Sym.Name+".lo", Types[TUINT32])
...@@ -4849,7 +4849,7 @@ func (e *ssaExport) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot { ...@@ -4849,7 +4849,7 @@ func (e *ssaExport) SplitStruct(name ssa.LocalSlot, i int) ssa.LocalSlot {
n := name.N.(*Node) n := name.N.(*Node)
st := name.Type st := name.Type
ft := st.FieldType(i) ft := st.FieldType(i)
if n.Class == PAUTO && !n.Addrtaken { if n.Class == PAUTO && !n.Addrtaken() {
// Note: the _ field may appear several times. But // Note: the _ field may appear several times. But
// have no fear, identically-named but distinct Autos are // have no fear, identically-named but distinct Autos are
// ok, albeit maybe confusing for a debugger. // ok, albeit maybe confusing for a debugger.
...@@ -4866,7 +4866,7 @@ func (e *ssaExport) SplitArray(name ssa.LocalSlot) ssa.LocalSlot { ...@@ -4866,7 +4866,7 @@ func (e *ssaExport) SplitArray(name ssa.LocalSlot) ssa.LocalSlot {
Fatalf("bad array size") Fatalf("bad array size")
} }
et := at.ElemType() et := at.ElemType()
if n.Class == PAUTO && !n.Addrtaken { if n.Class == PAUTO && !n.Addrtaken() {
x := e.namedAuto(n.Sym.Name+"[0]", et) x := e.namedAuto(n.Sym.Name+"[0]", et)
return ssa.LocalSlot{N: x, Type: et, Off: 0} return ssa.LocalSlot{N: x, Type: et, Off: 0}
} }
...@@ -4880,11 +4880,11 @@ func (e *ssaExport) namedAuto(name string, typ ssa.Type) ssa.GCNode { ...@@ -4880,11 +4880,11 @@ func (e *ssaExport) namedAuto(name string, typ ssa.Type) ssa.GCNode {
s := &Sym{Name: name, Pkg: localpkg} s := &Sym{Name: name, Pkg: localpkg}
n := nod(ONAME, nil, nil) n := nod(ONAME, nil, nil)
s.Def = n s.Def = n
s.Def.Used = true s.Def.SetUsed(true)
n.Sym = s n.Sym = s
n.Type = t n.Type = t
n.Class = PAUTO n.Class = PAUTO
n.Addable = true n.SetAddable(true)
n.Ullman = 1 n.Ullman = 1
n.Esc = EscNever n.Esc = EscNever
n.Xoffset = 0 n.Xoffset = 0
......
...@@ -342,7 +342,7 @@ func nod(op Op, nleft *Node, nright *Node) *Node { ...@@ -342,7 +342,7 @@ func nod(op Op, nleft *Node, nright *Node) *Node {
} }
n = &x.Node n = &x.Node
n.Func = &x.Func n.Func = &x.Func
n.Func.IsHiddenClosure = Curfn != nil n.Func.SetIsHiddenClosure(Curfn != nil)
case ONAME: case ONAME:
var x struct { var x struct {
Node Node
...@@ -422,7 +422,7 @@ func (x methcmp) Less(i, j int) bool { ...@@ -422,7 +422,7 @@ func (x methcmp) Less(i, j int) bool {
func nodintconst(v int64) *Node { func nodintconst(v int64) *Node {
c := nod(OLITERAL, nil, nil) c := nod(OLITERAL, nil, nil)
c.Addable = true c.SetAddable(true)
c.SetVal(Val{new(Mpint)}) c.SetVal(Val{new(Mpint)})
c.Val().U.(*Mpint).SetInt64(v) c.Val().U.(*Mpint).SetInt64(v)
c.Type = Types[TIDEAL] c.Type = Types[TIDEAL]
...@@ -432,7 +432,7 @@ func nodintconst(v int64) *Node { ...@@ -432,7 +432,7 @@ func nodintconst(v int64) *Node {
func nodfltconst(v *Mpflt) *Node { func nodfltconst(v *Mpflt) *Node {
c := nod(OLITERAL, nil, nil) c := nod(OLITERAL, nil, nil)
c.Addable = true c.SetAddable(true)
c.SetVal(Val{newMpflt()}) c.SetVal(Val{newMpflt()})
c.Val().U.(*Mpflt).Set(v) c.Val().U.(*Mpflt).Set(v)
c.Type = Types[TIDEAL] c.Type = Types[TIDEAL]
...@@ -443,7 +443,7 @@ func nodfltconst(v *Mpflt) *Node { ...@@ -443,7 +443,7 @@ func nodfltconst(v *Mpflt) *Node {
func nodconst(n *Node, t *Type, v int64) { func nodconst(n *Node, t *Type, v int64) {
*n = Node{} *n = Node{}
n.Op = OLITERAL n.Op = OLITERAL
n.Addable = true n.SetAddable(true)
ullmancalc(n) ullmancalc(n)
n.SetVal(Val{new(Mpint)}) n.SetVal(Val{new(Mpint)})
n.Val().U.(*Mpint).SetInt64(v) n.Val().U.(*Mpint).SetInt64(v)
...@@ -613,7 +613,7 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo ...@@ -613,7 +613,7 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo
if t1 == t2 { if t1 == t2 {
return true return true
} }
if t1 == nil || t2 == nil || t1.Etype != t2.Etype || t1.Broke || t2.Broke { if t1 == nil || t2 == nil || t1.Etype != t2.Etype || t1.Broke() || t2.Broke() {
return false return false
} }
if t1.Sym != nil || t2.Sym != nil { if t1.Sym != nil || t2.Sym != nil {
...@@ -660,7 +660,7 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo ...@@ -660,7 +660,7 @@ func eqtype1(t1, t2 *Type, cmpTags bool, assumedEqual map[typePair]struct{}) boo
ta, ia := iterFields(f(t1)) ta, ia := iterFields(f(t1))
tb, ib := iterFields(f(t2)) tb, ib := iterFields(f(t2))
for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() { for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() {
if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, cmpTags, assumedEqual) { if ta.Isddd() != tb.Isddd() || !eqtype1(ta.Type, tb.Type, cmpTags, assumedEqual) {
return false return false
} }
} }
...@@ -769,14 +769,14 @@ func assignop(src *Type, dst *Type, why *string) Op { ...@@ -769,14 +769,14 @@ func assignop(src *Type, dst *Type, why *string) Op {
} }
// we'll have complained about this method anyway, suppress spurious messages. // we'll have complained about this method anyway, suppress spurious messages.
if have != nil && have.Sym == missing.Sym && (have.Type.Broke || missing.Type.Broke) { if have != nil && have.Sym == missing.Sym && (have.Type.Broke() || missing.Type.Broke()) {
return OCONVIFACE return OCONVIFACE
} }
if why != nil { if why != nil {
if isptrto(src, TINTER) { if isptrto(src, TINTER) {
*why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src) *why = fmt.Sprintf(":\n\t%v is pointer to interface, not interface", src)
} else if have != nil && have.Sym == missing.Sym && have.Nointerface { } else if have != nil && have.Sym == missing.Sym && have.Nointerface() {
*why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym) *why = fmt.Sprintf(":\n\t%v does not implement %v (%v method is marked 'nointerface')", src, dst, missing.Sym)
} else if have != nil && have.Sym == missing.Sym { } else if have != nil && have.Sym == missing.Sym {
*why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+ *why = fmt.Sprintf(":\n\t%v does not implement %v (wrong type for %v method)\n"+
...@@ -861,7 +861,7 @@ func convertop(src *Type, dst *Type, why *string) Op { ...@@ -861,7 +861,7 @@ func convertop(src *Type, dst *Type, why *string) Op {
// Conversions from regular to go:notinheap are not allowed // Conversions from regular to go:notinheap are not allowed
// (unless it's unsafe.Pointer). This is a runtime-specific // (unless it's unsafe.Pointer). This is a runtime-specific
// rule. // rule.
if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap && !src.Elem().NotInHeap { if src.IsPtr() && dst.IsPtr() && dst.Elem().NotInHeap() && !src.Elem().NotInHeap() {
if why != nil { if why != nil {
*why = fmt.Sprintf(":\n\t%v is go:notinheap, but %v is not", dst.Elem(), src.Elem()) *why = fmt.Sprintf(":\n\t%v is go:notinheap, but %v is not", dst.Elem(), src.Elem())
} }
...@@ -959,7 +959,7 @@ func assignconv(n *Node, t *Type, context string) *Node { ...@@ -959,7 +959,7 @@ func assignconv(n *Node, t *Type, context string) *Node {
// Convert node n for assignment to type t. // Convert node n for assignment to type t.
func assignconvfn(n *Node, t *Type, context func() string) *Node { func assignconvfn(n *Node, t *Type, context func() string) *Node {
if n == nil || n.Type == nil || n.Type.Broke { if n == nil || n.Type == nil || n.Type.Broke() {
return n return n
} }
...@@ -968,10 +968,10 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node { ...@@ -968,10 +968,10 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node {
} }
old := n old := n
od := old.Diag od := old.Diag()
old.Diag = true // silence errors about n; we'll issue one below old.SetDiag(true) // silence errors about n; we'll issue one below
n = defaultlit(n, t) n = defaultlit(n, t)
old.Diag = od old.SetDiag(od)
if t.Etype == TBLANK { if t.Etype == TBLANK {
return n return n
} }
...@@ -983,7 +983,7 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node { ...@@ -983,7 +983,7 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node {
r := nod(OCONVNOP, n, nil) r := nod(OCONVNOP, n, nil)
r.Type = Types[TBOOL] r.Type = Types[TBOOL]
r.Typecheck = 1 r.Typecheck = 1
r.Implicit = true r.SetImplicit(true)
n = r n = r
} }
} }
...@@ -1002,7 +1002,7 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node { ...@@ -1002,7 +1002,7 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node {
r := nod(op, n, nil) r := nod(op, n, nil)
r.Type = t r.Type = t
r.Typecheck = 1 r.Typecheck = 1
r.Implicit = true r.SetImplicit(true)
r.Orig = n.Orig r.Orig = n.Orig
return r return r
} }
...@@ -1499,8 +1499,8 @@ func dotpath(s *Sym, t *Type, save **Field, ignorecase bool) (path []Dlist, ambi ...@@ -1499,8 +1499,8 @@ func dotpath(s *Sym, t *Type, save **Field, ignorecase bool) (path []Dlist, ambi
// modify the tree with missing type names. // modify the tree with missing type names.
func adddot(n *Node) *Node { func adddot(n *Node) *Node {
n.Left = typecheck(n.Left, Etype|Erv) n.Left = typecheck(n.Left, Etype|Erv)
if n.Left.Diag { if n.Left.Diag() {
n.Diag = true n.SetDiag(true)
} }
t := n.Left.Type t := n.Left.Type
if t == nil { if t == nil {
...@@ -1521,7 +1521,7 @@ func adddot(n *Node) *Node { ...@@ -1521,7 +1521,7 @@ func adddot(n *Node) *Node {
// rebuild elided dots // rebuild elided dots
for c := len(path) - 1; c >= 0; c-- { for c := len(path) - 1; c >= 0; c-- {
n.Left = nodSym(ODOT, n.Left, path[c].field.Sym) n.Left = nodSym(ODOT, n.Left, path[c].field.Sym)
n.Left.Implicit = true n.Left.SetImplicit(true)
} }
case ambig: case ambig:
yyerror("ambiguous selector %v", n) yyerror("ambiguous selector %v", n)
...@@ -1674,9 +1674,9 @@ func structargs(tl *Type, mustname bool) []*Node { ...@@ -1674,9 +1674,9 @@ func structargs(tl *Type, mustname bool) []*Node {
n = newname(t.Sym) n = newname(t.Sym)
} }
a := nod(ODCLFIELD, n, typenod(t.Type)) a := nod(ODCLFIELD, n, typenod(t.Type))
a.Isddd = t.Isddd a.SetIsddd(t.Isddd())
if n != nil { if n != nil {
n.Isddd = t.Isddd n.SetIsddd(t.Isddd())
} }
args = append(args, a) args = append(args, a)
} }
...@@ -1750,7 +1750,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) { ...@@ -1750,7 +1750,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
isddd := false isddd := false
for _, n := range in { for _, n := range in {
args = append(args, n.Left) args = append(args, n.Left)
isddd = n.Left.Isddd isddd = n.Left.Isddd()
} }
methodrcvr := method.Type.Recv().Type methodrcvr := method.Type.Recv().Type
...@@ -1788,12 +1788,12 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) { ...@@ -1788,12 +1788,12 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
n.Left = newname(methodsym(method.Sym, methodrcvr, 0)) n.Left = newname(methodsym(method.Sym, methodrcvr, 0))
fn.Nbody.Append(n) fn.Nbody.Append(n)
// When tail-calling, we can't use a frame pointer. // When tail-calling, we can't use a frame pointer.
fn.Func.NoFramePointer = true fn.Func.SetNoFramePointer(true)
} else { } else {
fn.Func.Wrapper = true // ignore frame for panic+recover matching fn.Func.SetWrapper(true) // ignore frame for panic+recover matching
call := nod(OCALL, dot, nil) call := nod(OCALL, dot, nil)
call.List.Set(args) call.List.Set(args)
call.Isddd = isddd call.SetIsddd(isddd)
if method.Type.Results().NumFields() > 0 { if method.Type.Results().NumFields() > 0 {
n := nod(ORETURN, nil, nil) n := nod(ORETURN, nil, nil)
n.List.Set1(call) n.List.Set1(call)
...@@ -1816,7 +1816,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) { ...@@ -1816,7 +1816,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
// wrappers where T is anonymous (struct or interface) can be duplicated. // wrappers where T is anonymous (struct or interface) can be duplicated.
if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() { if rcvr.IsStruct() || rcvr.IsInterface() || rcvr.IsPtr() && rcvr.Elem().IsStruct() {
fn.Func.Dupok = true fn.Func.SetDupok(true)
} }
fn = typecheck(fn, Etop) fn = typecheck(fn, Etop)
typecheckslice(fn.Nbody.Slice(), Etop) typecheckslice(fn.Nbody.Slice(), Etop)
...@@ -1913,12 +1913,12 @@ func implements(t, iface *Type, m, samename **Field, ptr *int) bool { ...@@ -1913,12 +1913,12 @@ func implements(t, iface *Type, m, samename **Field, ptr *int) bool {
expandmeth(t) expandmeth(t)
} }
for _, im := range iface.Fields().Slice() { for _, im := range iface.Fields().Slice() {
if im.Broke { if im.Broke() {
continue continue
} }
var followptr bool var followptr bool
tm := ifacelookdot(im.Sym, t, &followptr, false) tm := ifacelookdot(im.Sym, t, &followptr, false)
if tm == nil || tm.Nointerface || !eqtype(tm.Type, im.Type) { if tm == nil || tm.Nointerface() || !eqtype(tm.Type, im.Type) {
if tm == nil { if tm == nil {
tm = ifacelookdot(im.Sym, t, &followptr, true) tm = ifacelookdot(im.Sym, t, &followptr, true)
} }
...@@ -2126,7 +2126,7 @@ func itabType(itab *Node) *Node { ...@@ -2126,7 +2126,7 @@ func itabType(itab *Node) *Node {
typ.Type = ptrto(Types[TUINT8]) typ.Type = ptrto(Types[TUINT8])
typ.Typecheck = 1 typ.Typecheck = 1
typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab typ.Xoffset = int64(Widthptr) // offset of _type in runtime.itab
typ.Bounded = true // guaranteed not to fault typ.SetBounded(true) // guaranteed not to fault
return typ return typ
} }
...@@ -2141,7 +2141,7 @@ func ifaceData(n *Node, t *Type) *Node { ...@@ -2141,7 +2141,7 @@ func ifaceData(n *Node, t *Type) *Node {
return ptr return ptr
} }
ptr.Type = ptrto(t) ptr.Type = ptrto(t)
ptr.Bounded = true ptr.SetBounded(true)
ptr.Typecheck = 1 ptr.Typecheck = 1
ind := nod(OIND, ptr, nil) ind := nod(OIND, ptr, nil)
ind.Type = t ind.Type = t
......
...@@ -158,10 +158,10 @@ func typecheckswitch(n *Node) { ...@@ -158,10 +158,10 @@ func typecheckswitch(n *Node) {
n1 = n.Left.Right n1 = n.Left.Right
ls[i1] = n1 ls[i1] = n1
case !n1.Type.IsInterface() && t.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr): case !n1.Type.IsInterface() && t.IsInterface() && !implements(n1.Type, t, &missing, &have, &ptr):
if have != nil && !missing.Broke && !have.Broke { if have != nil && !missing.Broke() && !have.Broke() {
yyerror("impossible type switch case: %L cannot have dynamic type %v"+ yyerror("impossible type switch case: %L cannot have dynamic type %v"+
" (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left.Right, n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type) " (wrong type for %v method)\n\thave %v%S\n\twant %v%S", n.Left.Right, n1.Type, missing.Sym, have.Sym, have.Type, missing.Sym, missing.Type)
} else if !missing.Broke { } else if !missing.Broke() {
if ptr != 0 { if ptr != 0 {
yyerror("impossible type switch case: %L cannot have dynamic type %v"+ yyerror("impossible type switch case: %L cannot have dynamic type %v"+
" (%v method has pointer receiver)", n.Left.Right, n1.Type, missing.Sym) " (%v method has pointer receiver)", n.Left.Right, n1.Type, missing.Sym)
...@@ -760,7 +760,7 @@ func (s *typeSwitch) walk(sw *Node) { ...@@ -760,7 +760,7 @@ func (s *typeSwitch) walk(sw *Node) {
} else { } else {
h.Xoffset = int64(3 * Widthptr) // offset of hash in runtime.itab h.Xoffset = int64(3 * Widthptr) // offset of hash in runtime.itab
} }
h.Bounded = true // guaranteed not to fault h.SetBounded(true) // guaranteed not to fault
a = nod(OAS, s.hashname, h) a = nod(OAS, s.hashname, h)
a = typecheck(a, Etop) a = typecheck(a, Etop)
cas = append(cas, a) cas = append(cas, a)
......
This diff is collapsed.
...@@ -154,16 +154,33 @@ type Type struct { ...@@ -154,16 +154,33 @@ type Type struct {
Vargen int32 // unique name for OTYPE/ONAME Vargen int32 // unique name for OTYPE/ONAME
Pos src.XPos // position at which this type was declared, implicitly or explicitly Pos src.XPos // position at which this type was declared, implicitly or explicitly
Etype EType // kind of type Etype EType // kind of type
Noalg bool // suppress hash and eq algorithm generation Trecur uint8 // to detect loops
Trecur uint8 // to detect loops Align uint8 // the required alignment of this type, in bytes
Local bool // created in this file
Deferwidth bool flags bitset8
Broke bool // broken type definition.
Align uint8 // the required alignment of this type, in bytes
NotInHeap bool // type cannot be heap allocated
} }
const (
typeLocal = 1 << iota // created in this file
typeNotInHeap // type cannot be heap allocated
typeBroke // broken type definition
typeNoalg // suppress hash and eq algorithm generation
typeDeferwidth
)
func (t *Type) Local() bool { return t.flags&typeLocal != 0 }
func (t *Type) NotInHeap() bool { return t.flags&typeNotInHeap != 0 }
func (t *Type) Broke() bool { return t.flags&typeBroke != 0 }
func (t *Type) Noalg() bool { return t.flags&typeNoalg != 0 }
func (t *Type) Deferwidth() bool { return t.flags&typeDeferwidth != 0 }
func (t *Type) SetLocal(b bool) { t.flags.set(typeLocal, b) }
func (t *Type) SetNotInHeap(b bool) { t.flags.set(typeNotInHeap, b) }
func (t *Type) SetBroke(b bool) { t.flags.set(typeBroke, b) }
func (t *Type) SetNoalg(b bool) { t.flags.set(typeNoalg, b) }
func (t *Type) SetDeferwidth(b bool) { t.flags.set(typeDeferwidth, b) }
// MapType contains Type fields specific to maps. // MapType contains Type fields specific to maps.
type MapType struct { type MapType struct {
Key *Type // Key type Key *Type // Key type
...@@ -299,11 +316,10 @@ type SliceType struct { ...@@ -299,11 +316,10 @@ type SliceType struct {
// A Field represents a field in a struct or a method in an interface or // A Field represents a field in a struct or a method in an interface or
// associated with a named type. // associated with a named type.
type Field struct { type Field struct {
Nointerface bool flags bitset8
Embedded uint8 // embedded field
Funarg Funarg Embedded uint8 // embedded field
Broke bool // broken field definition Funarg Funarg
Isddd bool // field is ... argument
Sym *Sym Sym *Sym
Nname *Node Nname *Node
...@@ -317,6 +333,20 @@ type Field struct { ...@@ -317,6 +333,20 @@ type Field struct {
Note string // literal string annotation Note string // literal string annotation
} }
const (
fieldIsddd = 1 << iota // field is ... argument
fieldBroke // broken field definition
fieldNointerface
)
func (f *Field) Isddd() bool { return f.flags&fieldIsddd != 0 }
func (f *Field) Broke() bool { return f.flags&fieldBroke != 0 }
func (f *Field) Nointerface() bool { return f.flags&fieldNointerface != 0 }
func (f *Field) SetIsddd(b bool) { f.flags.set(fieldIsddd, b) }
func (f *Field) SetBroke(b bool) { f.flags.set(fieldBroke, b) }
func (f *Field) SetNointerface(b bool) { f.flags.set(fieldNointerface, b) }
// End returns the offset of the first byte immediately after this field. // End returns the offset of the first byte immediately after this field.
func (f *Field) End() int64 { func (f *Field) End() int64 {
return f.Offset + f.Type.Width return f.Offset + f.Type.Width
...@@ -416,7 +446,7 @@ func typArray(elem *Type, bound int64) *Type { ...@@ -416,7 +446,7 @@ func typArray(elem *Type, bound int64) *Type {
} }
t := typ(TARRAY) t := typ(TARRAY)
t.Extra = &ArrayType{Elem: elem, Bound: bound} t.Extra = &ArrayType{Elem: elem, Bound: bound}
t.NotInHeap = elem.NotInHeap t.SetNotInHeap(elem.NotInHeap())
return t return t
} }
...@@ -439,7 +469,7 @@ func typSlice(elem *Type) *Type { ...@@ -439,7 +469,7 @@ func typSlice(elem *Type) *Type {
func typDDDArray(elem *Type) *Type { func typDDDArray(elem *Type) *Type {
t := typ(TARRAY) t := typ(TARRAY)
t.Extra = &ArrayType{Elem: elem, Bound: -1} t.Extra = &ArrayType{Elem: elem, Bound: -1}
t.NotInHeap = elem.NotInHeap t.SetNotInHeap(elem.NotInHeap())
return t return t
} }
...@@ -832,8 +862,8 @@ func (t *Type) SetFields(fields []*Field) { ...@@ -832,8 +862,8 @@ func (t *Type) SetFields(fields []*Field) {
// you could heap allocate T and then get a pointer F, // you could heap allocate T and then get a pointer F,
// which would be a heap pointer to a go:notinheap // which would be a heap pointer to a go:notinheap
// type. // type.
if f.Type != nil && f.Type.NotInHeap { if f.Type != nil && f.Type.NotInHeap() {
t.NotInHeap = true t.SetNotInHeap(true)
break break
} }
} }
...@@ -1039,8 +1069,8 @@ func (t *Type) cmp(x *Type) ssa.Cmp { ...@@ -1039,8 +1069,8 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
ta, ia := iterFields(f(t)) ta, ia := iterFields(f(t))
tb, ib := iterFields(f(x)) tb, ib := iterFields(f(x))
for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() { for ; ta != nil && tb != nil; ta, tb = ia.Next(), ib.Next() {
if ta.Isddd != tb.Isddd { if ta.Isddd() != tb.Isddd() {
return cmpForNe(!ta.Isddd) return cmpForNe(!ta.Isddd())
} }
if c := ta.Type.cmp(tb.Type); c != ssa.CMPeq { if c := ta.Type.cmp(tb.Type); c != ssa.CMPeq {
return c return c
......
This diff is collapsed.
...@@ -36,22 +36,22 @@ func walk(fn *Node) { ...@@ -36,22 +36,22 @@ func walk(fn *Node) {
// Propagate the used flag for typeswitch variables up to the NONAME in it's definition. // Propagate the used flag for typeswitch variables up to the NONAME in it's definition.
for _, ln := range fn.Func.Dcl { for _, ln := range fn.Func.Dcl {
if ln.Op == ONAME && (ln.Class == PAUTO || ln.Class == PAUTOHEAP) && ln.Name.Defn != nil && ln.Name.Defn.Op == OTYPESW && ln.Used { if ln.Op == ONAME && (ln.Class == PAUTO || ln.Class == PAUTOHEAP) && ln.Name.Defn != nil && ln.Name.Defn.Op == OTYPESW && ln.Used() {
ln.Name.Defn.Left.Used = true ln.Name.Defn.Left.SetUsed(true)
} }
} }
for _, ln := range fn.Func.Dcl { for _, ln := range fn.Func.Dcl {
if ln.Op != ONAME || (ln.Class != PAUTO && ln.Class != PAUTOHEAP) || ln.Sym.Name[0] == '&' || ln.Used { if ln.Op != ONAME || (ln.Class != PAUTO && ln.Class != PAUTOHEAP) || ln.Sym.Name[0] == '&' || ln.Used() {
continue continue
} }
if defn := ln.Name.Defn; defn != nil && defn.Op == OTYPESW { if defn := ln.Name.Defn; defn != nil && defn.Op == OTYPESW {
if defn.Left.Used { if defn.Left.Used() {
continue continue
} }
lineno = defn.Left.Pos lineno = defn.Left.Pos
yyerror("%v declared and not used", ln.Sym) yyerror("%v declared and not used", ln.Sym)
defn.Left.Used = true // suppress repeats defn.Left.SetUsed(true) // suppress repeats
} else { } else {
lineno = ln.Pos lineno = ln.Pos
yyerror("%v declared and not used", ln.Sym) yyerror("%v declared and not used", ln.Sym)
...@@ -97,7 +97,7 @@ func paramoutheap(fn *Node) bool { ...@@ -97,7 +97,7 @@ func paramoutheap(fn *Node) bool {
for _, ln := range fn.Func.Dcl { for _, ln := range fn.Func.Dcl {
switch ln.Class { switch ln.Class {
case PPARAMOUT: case PPARAMOUT:
if ln.isParamStackCopy() || ln.Addrtaken { if ln.isParamStackCopy() || ln.Addrtaken() {
return true return true
} }
...@@ -229,7 +229,7 @@ func walkstmt(n *Node) *Node { ...@@ -229,7 +229,7 @@ func walkstmt(n *Node) *Node {
prealloc[v] = callnew(v.Type) prealloc[v] = callnew(v.Type)
} }
nn := nod(OAS, v.Name.Param.Heapaddr, prealloc[v]) nn := nod(OAS, v.Name.Param.Heapaddr, prealloc[v])
nn.Colas = true nn.SetColas(true)
nn = typecheck(nn, Etop) nn = typecheck(nn, Etop)
return walkstmt(nn) return walkstmt(nn)
} }
...@@ -487,7 +487,7 @@ func walkexpr(n *Node, init *Nodes) *Node { ...@@ -487,7 +487,7 @@ func walkexpr(n *Node, init *Nodes) *Node {
nn := nod(OIND, n.Name.Param.Heapaddr, nil) nn := nod(OIND, n.Name.Param.Heapaddr, nil)
nn = typecheck(nn, Erv) nn = typecheck(nn, Erv)
nn = walkexpr(nn, init) nn = walkexpr(nn, init)
nn.Left.NonNil = true nn.Left.SetNonNil(true)
return nn return nn
} }
...@@ -558,7 +558,7 @@ opswitch: ...@@ -558,7 +558,7 @@ opswitch:
n.Left = walkexpr(n.Left, init) n.Left = walkexpr(n.Left, init)
n.Right = walkexpr(n.Right, init) n.Right = walkexpr(n.Right, init)
t := n.Left.Type t := n.Left.Type
n.Bounded = bounded(n.Right, 8*t.Width) n.SetBounded(bounded(n.Right, 8*t.Width))
if Debug['m'] != 0 && n.Etype != 0 && !Isconst(n.Right, CTINT) { if Debug['m'] != 0 && n.Etype != 0 && !Isconst(n.Right, CTINT) {
Warn("shift bounds check elided") Warn("shift bounds check elided")
} }
...@@ -622,13 +622,13 @@ opswitch: ...@@ -622,13 +622,13 @@ opswitch:
n = mkcall("gorecover", n.Type, init, nod(OADDR, nodfp, nil)) n = mkcall("gorecover", n.Type, init, nod(OADDR, nodfp, nil))
case OLITERAL: case OLITERAL:
n.Addable = true n.SetAddable(true)
case OCLOSUREVAR, OCFUNC: case OCLOSUREVAR, OCFUNC:
n.Addable = true n.SetAddable(true)
case ONAME: case ONAME:
n.Addable = true n.SetAddable(true)
case OCALLINTER: case OCALLINTER:
usemethod(n) usemethod(n)
...@@ -638,7 +638,7 @@ opswitch: ...@@ -638,7 +638,7 @@ opswitch:
} }
n.Left = walkexpr(n.Left, init) n.Left = walkexpr(n.Left, init)
walkexprlist(n.List.Slice(), init) walkexprlist(n.List.Slice(), init)
ll := ascompatte(n, n.Isddd, t.Params(), n.List.Slice(), 0, init) ll := ascompatte(n, n.Isddd(), t.Params(), n.List.Slice(), 0, init)
n.List.Set(reorder1(ll)) n.List.Set(reorder1(ll))
case OCALLFUNC: case OCALLFUNC:
...@@ -671,7 +671,7 @@ opswitch: ...@@ -671,7 +671,7 @@ opswitch:
n.Left = walkexpr(n.Left, init) n.Left = walkexpr(n.Left, init)
walkexprlist(n.List.Slice(), init) walkexprlist(n.List.Slice(), init)
ll := ascompatte(n, n.Isddd, t.Params(), n.List.Slice(), 0, init) ll := ascompatte(n, n.Isddd(), t.Params(), n.List.Slice(), 0, init)
n.List.Set(reorder1(ll)) n.List.Set(reorder1(ll))
case OCALLMETH: case OCALLMETH:
...@@ -682,7 +682,7 @@ opswitch: ...@@ -682,7 +682,7 @@ opswitch:
n.Left = walkexpr(n.Left, init) n.Left = walkexpr(n.Left, init)
walkexprlist(n.List.Slice(), init) walkexprlist(n.List.Slice(), init)
ll := ascompatte(n, false, t.Recvs(), []*Node{n.Left.Left}, 0, init) ll := ascompatte(n, false, t.Recvs(), []*Node{n.Left.Left}, 0, init)
lr := ascompatte(n, n.Isddd, t.Params(), n.List.Slice(), 0, init) lr := ascompatte(n, n.Isddd(), t.Params(), n.List.Slice(), 0, init)
ll = append(ll, lr...) ll = append(ll, lr...)
n.Left.Left = nil n.Left.Left = nil
ullmancalc(n.Left) ullmancalc(n.Left)
...@@ -725,10 +725,10 @@ opswitch: ...@@ -725,10 +725,10 @@ opswitch:
case OAPPEND: case OAPPEND:
// x = append(...) // x = append(...)
r := n.Right r := n.Right
if r.Type.Elem().NotInHeap { if r.Type.Elem().NotInHeap() {
yyerror("%v is go:notinheap; heap allocation disallowed", r.Type.Elem()) yyerror("%v is go:notinheap; heap allocation disallowed", r.Type.Elem())
} }
if r.Isddd { if r.Isddd() {
r = appendslice(r, init) // also works for append(slice, string). r = appendslice(r, init) // also works for append(slice, string).
} else { } else {
r = walkappend(r, init, n) r = walkappend(r, init, n)
...@@ -844,7 +844,7 @@ opswitch: ...@@ -844,7 +844,7 @@ opswitch:
if !isblank(a) { if !isblank(a) {
var_ := temp(ptrto(t.Val())) var_ := temp(ptrto(t.Val()))
var_.Typecheck = 1 var_.Typecheck = 1
var_.NonNil = true // mapaccess always returns a non-nil pointer var_.SetNonNil(true) // mapaccess always returns a non-nil pointer
n.List.SetFirst(var_) n.List.SetFirst(var_)
n = walkexpr(n, init) n = walkexpr(n, init)
init.Append(n) init.Append(n)
...@@ -915,8 +915,8 @@ opswitch: ...@@ -915,8 +915,8 @@ opswitch:
// n.Left is a bool/byte. Use staticbytes[n.Left]. // n.Left is a bool/byte. Use staticbytes[n.Left].
n.Left = cheapexpr(n.Left, init) n.Left = cheapexpr(n.Left, init)
value = nod(OINDEX, staticbytes, byteindex(n.Left)) value = nod(OINDEX, staticbytes, byteindex(n.Left))
value.Bounded = true value.SetBounded(true)
case n.Left.Class == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly: case n.Left.Class == PEXTERN && n.Left.Name != nil && n.Left.Name.Readonly():
// n.Left is a readonly global; use it directly. // n.Left is a readonly global; use it directly.
value = n.Left value = n.Left
case !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024: case !n.Left.Type.IsInterface() && n.Esc == EscNone && n.Left.Type.Width <= 1024:
...@@ -1143,7 +1143,7 @@ opswitch: ...@@ -1143,7 +1143,7 @@ opswitch:
// if range of type cannot exceed static array bound, // if range of type cannot exceed static array bound,
// disable bounds check. // disable bounds check.
if n.Bounded { if n.Bounded() {
break break
} }
t := n.Left.Type t := n.Left.Type
...@@ -1151,19 +1151,19 @@ opswitch: ...@@ -1151,19 +1151,19 @@ opswitch:
t = t.Elem() t = t.Elem()
} }
if t.IsArray() { if t.IsArray() {
n.Bounded = bounded(r, t.NumElem()) n.SetBounded(bounded(r, t.NumElem()))
if Debug['m'] != 0 && n.Bounded && !Isconst(n.Right, CTINT) { if Debug['m'] != 0 && n.Bounded() && !Isconst(n.Right, CTINT) {
Warn("index bounds check elided") Warn("index bounds check elided")
} }
if smallintconst(n.Right) && !n.Bounded { if smallintconst(n.Right) && !n.Bounded() {
yyerror("index out of bounds") yyerror("index out of bounds")
} }
} else if Isconst(n.Left, CTSTR) { } else if Isconst(n.Left, CTSTR) {
n.Bounded = bounded(r, int64(len(n.Left.Val().U.(string)))) n.SetBounded(bounded(r, int64(len(n.Left.Val().U.(string)))))
if Debug['m'] != 0 && n.Bounded && !Isconst(n.Right, CTINT) { if Debug['m'] != 0 && n.Bounded() && !Isconst(n.Right, CTINT) {
Warn("index bounds check elided") Warn("index bounds check elided")
} }
if smallintconst(n.Right) && !n.Bounded { if smallintconst(n.Right) && !n.Bounded() {
yyerror("index out of bounds") yyerror("index out of bounds")
} }
} }
...@@ -1205,7 +1205,7 @@ opswitch: ...@@ -1205,7 +1205,7 @@ opswitch:
} }
} }
n.Type = ptrto(t.Val()) n.Type = ptrto(t.Val())
n.NonNil = true // mapaccess1* and mapassign always return non-nil pointers. n.SetNonNil(true) // mapaccess1* and mapassign always return non-nil pointers.
n = nod(OIND, n, nil) n = nod(OIND, n, nil)
n.Type = t.Val() n.Type = t.Val()
n.Typecheck = 1 n.Typecheck = 1
...@@ -1435,7 +1435,7 @@ opswitch: ...@@ -1435,7 +1435,7 @@ opswitch:
// When len and cap can fit into int, use makeslice instead of // When len and cap can fit into int, use makeslice instead of
// makeslice64, which is faster and shorter on 32 bit platforms. // makeslice64, which is faster and shorter on 32 bit platforms.
if t.Elem().NotInHeap { if t.Elem().NotInHeap() {
yyerror("%v is go:notinheap; heap allocation disallowed", t.Elem()) yyerror("%v is go:notinheap; heap allocation disallowed", t.Elem())
} }
...@@ -1580,7 +1580,7 @@ opswitch: ...@@ -1580,7 +1580,7 @@ opswitch:
// n can be directly represented in the read-only data section. // n can be directly represented in the read-only data section.
// Make direct reference to the static data. See issue 12841. // Make direct reference to the static data. See issue 12841.
vstat := staticname(n.Type) vstat := staticname(n.Type)
vstat.Name.Readonly = true vstat.Name.SetReadonly(true)
fixedlit(inInitFunction, initKindStatic, n, vstat, init) fixedlit(inInitFunction, initKindStatic, n, vstat, init)
n = vstat n = vstat
n = typecheck(n, Erv) n = typecheck(n, Erv)
...@@ -1831,7 +1831,7 @@ func ascompatte(call *Node, isddd bool, lhs *Type, rhs []*Node, fp int, init *No ...@@ -1831,7 +1831,7 @@ func ascompatte(call *Node, isddd bool, lhs *Type, rhs []*Node, fp int, init *No
// then assign the remaining arguments as a slice. // then assign the remaining arguments as a slice.
for i, nl := range lhs.FieldSlice() { for i, nl := range lhs.FieldSlice() {
var nr *Node var nr *Node
if nl.Isddd && !isddd { if nl.Isddd() && !isddd {
nr = mkdotargslice(nl.Type, rhs[i:], init, call.Right) nr = mkdotargslice(nl.Type, rhs[i:], init, call.Right)
} else { } else {
nr = rhs[i] nr = rhs[i]
...@@ -1963,14 +1963,14 @@ func walkprint(nn *Node, init *Nodes) *Node { ...@@ -1963,14 +1963,14 @@ func walkprint(nn *Node, init *Nodes) *Node {
} }
func callnew(t *Type) *Node { func callnew(t *Type) *Node {
if t.NotInHeap { if t.NotInHeap() {
yyerror("%v is go:notinheap; heap allocation disallowed", t) yyerror("%v is go:notinheap; heap allocation disallowed", t)
} }
dowidth(t) dowidth(t)
fn := syslook("newobject") fn := syslook("newobject")
fn = substArgTypes(fn, t) fn = substArgTypes(fn, t)
v := mkcall1(fn, ptrto(t), nil, typename(t)) v := mkcall1(fn, ptrto(t), nil, typename(t))
v.NonNil = true v.SetNonNil(true)
return v return v
} }
...@@ -2058,7 +2058,7 @@ func needwritebarrier(l *Node) bool { ...@@ -2058,7 +2058,7 @@ func needwritebarrier(l *Node) bool {
// No write barrier if this is a pointer to a go:notinheap // No write barrier if this is a pointer to a go:notinheap
// type, since the write barrier's inheap(ptr) check will fail. // type, since the write barrier's inheap(ptr) check will fail.
if l.Type.IsPtr() && l.Type.Elem().NotInHeap { if l.Type.IsPtr() && l.Type.Elem().NotInHeap() {
return false return false
} }
...@@ -2308,7 +2308,7 @@ func aliased(n *Node, all []*Node, i int) bool { ...@@ -2308,7 +2308,7 @@ func aliased(n *Node, all []*Node, i int) bool {
continue continue
case PAUTO, PPARAM, PPARAMOUT: case PAUTO, PPARAM, PPARAMOUT:
if n.Addrtaken { if n.Addrtaken() {
varwrite = 1 varwrite = 1
continue continue
} }
...@@ -2356,7 +2356,7 @@ func varexpr(n *Node) bool { ...@@ -2356,7 +2356,7 @@ func varexpr(n *Node) bool {
case ONAME: case ONAME:
switch n.Class { switch n.Class {
case PAUTO, PPARAM, PPARAMOUT: case PAUTO, PPARAM, PPARAMOUT:
if !n.Addrtaken { if !n.Addrtaken() {
return true return true
} }
} }
...@@ -2790,7 +2790,7 @@ func appendslice(n *Node, init *Nodes) *Node { ...@@ -2790,7 +2790,7 @@ func appendslice(n *Node, init *Nodes) *Node {
} else { } else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T)) // memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil)) nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil))
nptr1.Bounded = true nptr1.SetBounded(true)
nptr1 = nod(OADDR, nptr1, nil) nptr1 = nod(OADDR, nptr1, nil)
...@@ -2895,7 +2895,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node { ...@@ -2895,7 +2895,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
ls = n.List.Slice()[1:] ls = n.List.Slice()[1:]
for i, n := range ls { for i, n := range ls {
nx = nod(OINDEX, ns, nn) // s[n] ... nx = nod(OINDEX, ns, nn) // s[n] ...
nx.Bounded = true nx.SetBounded(true)
l = append(l, nod(OAS, nx, n)) // s[n] = arg l = append(l, nod(OAS, nx, n)) // s[n] = arg
if i+1 < len(ls) { if i+1 < len(ls) {
l = append(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))) // n = n + 1 l = append(l, nod(OAS, nn, nod(OADD, nn, nodintconst(1)))) // n = n + 1
...@@ -3410,7 +3410,7 @@ func usemethod(n *Node) { ...@@ -3410,7 +3410,7 @@ func usemethod(n *Node) {
return return
} }
Curfn.Func.ReflectMethod = true Curfn.Func.SetReflectMethod(true)
} }
func usefield(n *Node) { func usefield(n *Node) {
......
...@@ -28,7 +28,7 @@ func defframe(ptxt *obj.Prog) { ...@@ -28,7 +28,7 @@ func defframe(ptxt *obj.Prog) {
// iterate through declarations - they are sorted in decreasing xoffset order. // iterate through declarations - they are sorted in decreasing xoffset order.
for _, n := range gc.Curfn.Func.Dcl { for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero { if !n.Name.Needzero() {
continue continue
} }
if n.Class != gc.PAUTO { if n.Class != gc.PAUTO {
......
...@@ -28,7 +28,7 @@ func defframe(ptxt *obj.Prog) { ...@@ -28,7 +28,7 @@ func defframe(ptxt *obj.Prog) {
// iterate through declarations - they are sorted in decreasing xoffset order. // iterate through declarations - they are sorted in decreasing xoffset order.
for _, n := range gc.Curfn.Func.Dcl { for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero { if !n.Name.Needzero() {
continue continue
} }
if n.Class != gc.PAUTO { if n.Class != gc.PAUTO {
......
...@@ -28,7 +28,7 @@ func defframe(ptxt *obj.Prog) { ...@@ -28,7 +28,7 @@ func defframe(ptxt *obj.Prog) {
// iterate through declarations - they are sorted in decreasing xoffset order. // iterate through declarations - they are sorted in decreasing xoffset order.
for _, n := range gc.Curfn.Func.Dcl { for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero { if !n.Name.Needzero() {
continue continue
} }
if n.Class != gc.PAUTO { if n.Class != gc.PAUTO {
......
...@@ -34,7 +34,7 @@ func defframe(ptxt *obj.Prog) { ...@@ -34,7 +34,7 @@ func defframe(ptxt *obj.Prog) {
// iterate through declarations - they are sorted in decreasing xoffset order. // iterate through declarations - they are sorted in decreasing xoffset order.
for _, n := range gc.Curfn.Func.Dcl { for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero { if !n.Name.Needzero() {
continue continue
} }
if n.Class != gc.PAUTO { if n.Class != gc.PAUTO {
......
...@@ -27,7 +27,7 @@ func defframe(ptxt *obj.Prog) { ...@@ -27,7 +27,7 @@ func defframe(ptxt *obj.Prog) {
lo := hi lo := hi
ax := uint32(0) ax := uint32(0)
for _, n := range gc.Curfn.Func.Dcl { for _, n := range gc.Curfn.Func.Dcl {
if !n.Name.Needzero { if !n.Name.Needzero() {
continue continue
} }
if n.Class != gc.PAUTO { if n.Class != gc.PAUTO {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment