Commit fc08a19c authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: move Used from gc.Node to gc.Name

Node.Used was written to from the backend
concurrently with reads of Node.Class
for the same ONAME Nodes.
I do not know why it was not failing consistently
under the race detector, but it is a race.

This is likely also a problem with Node.HasVal and Node.HasOpt.
They will be handled in a separate CL.

Fix Used by moving it to gc.Name and making it a separate bool.
There was one non-Name use of Used, marking OLABELs as used.
That is no longer needed, now that goto and label checking
happens early in the front end.

Leave the getters and setters in place,
to ease changing the representation in the future
(or changing to an interface!).

Updates #20144

Change-Id: I9bec7c6d33dcb129a4cfa9d338462ea33087f9f7
Reviewed-on: https://go-review.googlesource.com/42015
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 94d540a4
...@@ -398,7 +398,7 @@ func transformclosure(xfunc *Node) { ...@@ -398,7 +398,7 @@ func transformclosure(xfunc *Node) {
addr := newname(lookup("&" + v.Sym.Name)) addr := newname(lookup("&" + v.Sym.Name))
addr.Type = types.NewPtr(v.Type) addr.Type = types.NewPtr(v.Type)
addr.SetClass(PAUTO) addr.SetClass(PAUTO)
addr.SetUsed(true) addr.Name.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
...@@ -622,7 +622,7 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node { ...@@ -622,7 +622,7 @@ func makepartialcall(fn *Node, t0 *types.Type, meth *types.Sym) *Node {
} }
ptr := newname(lookup("rcvr")) ptr := newname(lookup("rcvr"))
ptr.SetClass(PAUTO) ptr.SetClass(PAUTO)
ptr.SetUsed(true) ptr.Name.SetUsed(true)
ptr.Name.Curfn = xfunc ptr.Name.Curfn = xfunc
xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr) xfunc.Func.Dcl = append(xfunc.Func.Dcl, ptr)
var body []*Node var body []*Node
......
...@@ -1443,7 +1443,7 @@ func (e *EscState) initEscRetval(call *Node, fntype *types.Type) { ...@@ -1443,7 +1443,7 @@ func (e *EscState) initEscRetval(call *Node, fntype *types.Type) {
ret.SetClass(PAUTO) ret.SetClass(PAUTO)
ret.Name.Curfn = Curfn ret.Name.Curfn = Curfn
e.nodeEscState(ret).Loopdepth = e.loopdepth e.nodeEscState(ret).Loopdepth = e.loopdepth
ret.SetUsed(true) ret.Name.SetUsed(true)
ret.Pos = call.Pos ret.Pos = call.Pos
cE.Retval.Append(ret) cE.Retval.Append(ret)
} }
......
...@@ -520,11 +520,11 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) { ...@@ -520,11 +520,11 @@ func (n *Node) jconv(s fmt.State, flag FmtFlag) {
} }
if c == 0 && n.HasCall() { if c == 0 && n.HasCall() {
fmt.Fprintf(s, " hascall") fmt.Fprint(s, " hascall")
} }
if c == 0 && n.Used() { if c == 0 && n.Name != nil && n.Name.Used() {
fmt.Fprintf(s, " used(%v)", n.Used()) fmt.Fprint(s, " used")
} }
} }
......
...@@ -71,13 +71,13 @@ func tempnamel(pos src.XPos, curfn *Node, nn *Node, t *types.Type) { ...@@ -71,13 +71,13 @@ func tempnamel(pos src.XPos, curfn *Node, nn *Node, t *types.Type) {
func temp(t *types.Type) *Node { func temp(t *types.Type) *Node {
var n Node var n Node
tempnamel(lineno, Curfn, &n, t) tempnamel(lineno, Curfn, &n, t)
asNode(n.Sym.Def).SetUsed(true) asNode(n.Sym.Def).Name.SetUsed(true)
return n.Orig return n.Orig
} }
func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node { func tempAt(pos src.XPos, curfn *Node, t *types.Type) *Node {
var n Node var n Node
tempnamel(pos, curfn, &n, t) tempnamel(pos, curfn, &n, t)
asNode(n.Sym.Def).SetUsed(true) asNode(n.Sym.Def).Name.SetUsed(true)
return n.Orig return n.Orig
} }
...@@ -745,7 +745,6 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node { ...@@ -745,7 +745,6 @@ 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.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)
...@@ -817,7 +816,7 @@ func inlvar(var_ *Node) *Node { ...@@ -817,7 +816,7 @@ func inlvar(var_ *Node) *Node {
n := newname(var_.Sym) n := newname(var_.Sym)
n.Type = var_.Type n.Type = var_.Type
n.SetClass(PAUTO) n.SetClass(PAUTO)
n.SetUsed(true) n.Name.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.SetAddrtaken(var_.Addrtaken()) n.SetAddrtaken(var_.Addrtaken())
...@@ -830,7 +829,7 @@ func retvar(t *types.Field, i int) *Node { ...@@ -830,7 +829,7 @@ func retvar(t *types.Field, i int) *Node {
n := newname(lookupN("~r", i)) n := newname(lookupN("~r", i))
n.Type = t.Type n.Type = t.Type
n.SetClass(PAUTO) n.SetClass(PAUTO)
n.SetUsed(true) n.Name.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
...@@ -842,7 +841,7 @@ func argvar(t *types.Type, i int) *Node { ...@@ -842,7 +841,7 @@ func argvar(t *types.Type, i int) *Node {
n := newname(lookupN("~arg", i)) n := newname(lookupN("~arg", i))
n.Type = t.Elem() n.Type = t.Elem()
n.SetClass(PAUTO) n.SetClass(PAUTO)
n.SetUsed(true) n.Name.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
......
...@@ -1046,7 +1046,7 @@ func clearImports() { ...@@ -1046,7 +1046,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 !asNode(s.Def).Used() && nsyntaxerrors == 0 { if !asNode(s.Def).Name.Used() && nsyntaxerrors == 0 {
pkgnotused(asNode(s.Def).Pos, asNode(s.Def).Name.Pkg.Path, s.Name) pkgnotused(asNode(s.Def).Pos, asNode(s.Def).Name.Pkg.Path, s.Name)
} }
s.Def = nil s.Def = nil
...@@ -1056,9 +1056,9 @@ func clearImports() { ...@@ -1056,9 +1056,9 @@ func clearImports() {
if IsAlias(s) { if IsAlias(s) {
// throw away top-level name left over // throw away top-level name left over
// from previous import . "x" // from previous import . "x"
if asNode(s.Def).Name != nil && asNode(s.Def).Name.Pack != nil && !asNode(s.Def).Name.Pack.Used() && nsyntaxerrors == 0 { if asNode(s.Def).Name != nil && asNode(s.Def).Name.Pack != nil && !asNode(s.Def).Name.Pack.Name.Used() && nsyntaxerrors == 0 {
pkgnotused(asNode(s.Def).Name.Pack.Pos, asNode(s.Def).Name.Pack.Name.Pkg.Path, "") pkgnotused(asNode(s.Def).Name.Pack.Pos, asNode(s.Def).Name.Pack.Name.Pkg.Path, "")
asNode(s.Def).Name.Pack.SetUsed(true) asNode(s.Def).Name.Pack.Name.SetUsed(true)
} }
s.Def = nil s.Def = nil
......
...@@ -449,7 +449,7 @@ func (p *noder) expr(expr syntax.Expr) *Node { ...@@ -449,7 +449,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.SetUsed(true) obj.Name.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)))
...@@ -611,7 +611,7 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym { ...@@ -611,7 +611,7 @@ func (p *noder) packname(expr syntax.Expr) *types.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.SetUsed(true) n.Name.Pack.Name.SetUsed(true)
} }
return name return name
case *syntax.SelectorExpr: case *syntax.SelectorExpr:
...@@ -621,7 +621,7 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym { ...@@ -621,7 +621,7 @@ func (p *noder) packname(expr syntax.Expr) *types.Sym {
yyerror("%v is not a package", name) yyerror("%v is not a package", name)
pkg = localpkg pkg = localpkg
} else { } else {
asNode(name.Def).SetUsed(true) asNode(name.Def).Name.SetUsed(true)
pkg = asNode(name.Def).Name.Pkg pkg = asNode(name.Def).Name.Pkg
} }
return restrictlookup(expr.Sel.Value, pkg) return restrictlookup(expr.Sel.Value, pkg)
...@@ -1125,7 +1125,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma { ...@@ -1125,7 +1125,7 @@ func (p *noder) pragma(pos src.Pos, text string) syntax.Pragma {
func mkname(sym *types.Sym) *Node { func mkname(sym *types.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.SetUsed(true) n.Name.Pack.Name.SetUsed(true)
} }
return n return n
} }
......
...@@ -80,8 +80,8 @@ func cmpstackvarlt(a, b *Node) bool { ...@@ -80,8 +80,8 @@ func cmpstackvarlt(a, b *Node) bool {
return a.Xoffset < b.Xoffset return a.Xoffset < b.Xoffset
} }
if a.Used() != b.Used() { if a.Name.Used() != b.Name.Used() {
return a.Used() return a.Name.Used()
} }
ap := types.Haspointers(a.Type) ap := types.Haspointers(a.Type)
...@@ -118,13 +118,13 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { ...@@ -118,13 +118,13 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
// Mark the PAUTO's unused. // Mark the PAUTO's unused.
for _, ln := range fn.Dcl { for _, ln := range fn.Dcl {
if ln.Class() == PAUTO { if ln.Class() == PAUTO {
ln.SetUsed(false) ln.Name.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).SetUsed(true) ls.N.(*Node).Name.SetUsed(true)
} }
} }
...@@ -136,10 +136,10 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { ...@@ -136,10 +136,10 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
n := a.Node.(*Node) n := a.Node.(*Node)
// Don't modify nodfp; it is a global. // Don't modify nodfp; it is a global.
if n != nodfp { if n != nodfp {
n.SetUsed(true) n.Name.SetUsed(true)
} }
case *ssa.AutoSymbol: case *ssa.AutoSymbol:
a.Node.(*Node).SetUsed(true) a.Node.(*Node).Name.SetUsed(true)
} }
if !scratchUsed { if !scratchUsed {
...@@ -159,7 +159,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) { ...@@ -159,7 +159,7 @@ func (s *ssafn) 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.Name.Used() {
fn.Dcl = fn.Dcl[:i] fn.Dcl = fn.Dcl[:i]
break break
} }
...@@ -308,7 +308,7 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var { ...@@ -308,7 +308,7 @@ func debuginfo(fnsym *obj.LSym, curfn interface{}) []*dwarf.Var {
switch n.Class() { switch n.Class() {
case PAUTO: case PAUTO:
if !n.Used() { if !n.Name.Used() {
Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)") Fatalf("debuginfo unused node (AllocFrame should truncate fn.Func.Dcl)")
} }
name = obj.NAME_AUTO name = obj.NAME_AUTO
......
...@@ -25,8 +25,19 @@ func typeWithPointers() *types.Type { ...@@ -25,8 +25,19 @@ func typeWithPointers() *types.Type {
return t return t
} }
func markUsed(n *Node) *Node {
n.Name.SetUsed(true)
return n
}
func markNeedZero(n *Node) *Node {
n.Name.SetNeedzero(true)
return n
}
func nodeWithClass(n Node, c Class) *Node { func nodeWithClass(n Node, c Class) *Node {
n.SetClass(c) n.SetClass(c)
n.Name = new(Name)
return &n return &n
} }
...@@ -72,13 +83,13 @@ func TestCmpstackvar(t *testing.T) { ...@@ -72,13 +83,13 @@ func TestCmpstackvar(t *testing.T) {
true, true,
}, },
{ {
nodeWithClass(Node{flags: nodeUsed}, PAUTO), markUsed(nodeWithClass(Node{}, PAUTO)),
nodeWithClass(Node{}, PAUTO), nodeWithClass(Node{}, PAUTO),
true, true,
}, },
{ {
nodeWithClass(Node{}, PAUTO), nodeWithClass(Node{}, PAUTO),
nodeWithClass(Node{flags: nodeUsed}, PAUTO), markUsed(nodeWithClass(Node{}, PAUTO)),
false, false,
}, },
{ {
...@@ -92,13 +103,13 @@ func TestCmpstackvar(t *testing.T) { ...@@ -92,13 +103,13 @@ func TestCmpstackvar(t *testing.T) {
true, true,
}, },
{ {
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{flags: nameNeedzero}}, PAUTO), markNeedZero(nodeWithClass(Node{Type: &types.Type{}}, PAUTO)),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}}, PAUTO),
true, true,
}, },
{ {
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{flags: nameNeedzero}}, PAUTO), markNeedZero(nodeWithClass(Node{Type: &types.Type{}}, PAUTO)),
false, false,
}, },
{ {
...@@ -112,18 +123,18 @@ func TestCmpstackvar(t *testing.T) { ...@@ -112,18 +123,18 @@ func TestCmpstackvar(t *testing.T) {
true, true,
}, },
{ {
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
true, true,
}, },
{ {
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
false, false,
}, },
{ {
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
false, false,
}, },
} }
...@@ -141,34 +152,34 @@ func TestCmpstackvar(t *testing.T) { ...@@ -141,34 +152,34 @@ func TestCmpstackvar(t *testing.T) {
func TestStackvarSort(t *testing.T) { func TestStackvarSort(t *testing.T) {
inp := []*Node{ inp := []*Node{
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PFUNC), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Xoffset: 0, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PFUNC), nodeWithClass(Node{Xoffset: 0, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
nodeWithClass(Node{Xoffset: 10, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PFUNC), nodeWithClass(Node{Xoffset: 10, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
nodeWithClass(Node{Xoffset: 20, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PFUNC), nodeWithClass(Node{Xoffset: 20, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
nodeWithClass(Node{flags: nodeUsed, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), markUsed(nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO)),
nodeWithClass(Node{Type: typeWithoutPointers(), Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: typeWithoutPointers(), Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{flags: nameNeedzero}, Sym: &types.Sym{}}, PAUTO), markNeedZero(nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO)),
nodeWithClass(Node{Type: &types.Type{Width: 1}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{Width: 1}, Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{Width: 2}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{Width: 2}, Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
} }
want := []*Node{ want := []*Node{
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PFUNC), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
nodeWithClass(Node{Xoffset: 0, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PFUNC), nodeWithClass(Node{Xoffset: 0, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
nodeWithClass(Node{Xoffset: 10, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PFUNC), nodeWithClass(Node{Xoffset: 10, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
nodeWithClass(Node{Xoffset: 20, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PFUNC), nodeWithClass(Node{Xoffset: 20, Type: &types.Type{}, Sym: &types.Sym{}}, PFUNC),
nodeWithClass(Node{flags: nodeUsed, Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), markUsed(nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO)),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{flags: nameNeedzero}, Sym: &types.Sym{}}, PAUTO), markNeedZero(nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO)),
nodeWithClass(Node{Type: &types.Type{Width: 2}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{Width: 2}, Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{Width: 1}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{Width: 1}, Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "abc"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "abc"}}, PAUTO),
nodeWithClass(Node{Type: &types.Type{}, Name: &Name{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO), nodeWithClass(Node{Type: &types.Type{}, Sym: &types.Sym{Name: "xyz"}}, PAUTO),
nodeWithClass(Node{Type: typeWithoutPointers(), Name: &Name{}, Sym: &types.Sym{}}, PAUTO), nodeWithClass(Node{Type: typeWithoutPointers(), Sym: &types.Sym{}}, PAUTO),
} }
// haspointers updates Type.Haspointers as a side effect, so // haspointers updates Type.Haspointers as a side effect, so
// exercise this function on all inputs so that reflect.DeepEqual // exercise this function on all inputs so that reflect.DeepEqual
......
...@@ -250,7 +250,7 @@ func (lv *Liveness) valueEffects(v *ssa.Value) (pos int32, effect liveEffect) { ...@@ -250,7 +250,7 @@ func (lv *Liveness) valueEffects(v *ssa.Value) (pos int32, effect liveEffect) {
// variable" ICEs (issue 19632). // variable" ICEs (issue 19632).
switch v.Op { switch v.Op {
case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive: case ssa.OpVarDef, ssa.OpVarKill, ssa.OpVarLive, ssa.OpKeepAlive:
if !n.Used() { if !n.Name.Used() {
return -1, 0 return -1, 0
} }
} }
......
...@@ -4964,7 +4964,7 @@ func (e *ssafn) namedAuto(name string, typ ssa.Type, pos src.XPos) ssa.GCNode { ...@@ -4964,7 +4964,7 @@ func (e *ssafn) namedAuto(name string, typ ssa.Type, pos src.XPos) ssa.GCNode {
n.Orig = n n.Orig = n
s.Def = asTypesNode(n) s.Def = asTypesNode(n)
asNode(s.Def).SetUsed(true) asNode(s.Def).Name.SetUsed(true)
n.Sym = s n.Sym = s
n.Type = t n.Type = t
n.SetClass(PAUTO) n.SetClass(PAUTO)
......
...@@ -93,7 +93,6 @@ const ( ...@@ -93,7 +93,6 @@ const (
_, nodeNoescape // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360) _, nodeNoescape // func arguments do not escape; TODO(rsc): move Noescape to Func struct (see CL 7360)
_, nodeBounded // bounds check unnecessary _, nodeBounded // bounds check unnecessary
_, nodeAddable // addressable _, nodeAddable // addressable
_, nodeUsed // for variable/label declared and not used error
_, nodeHasCall // expression contains a function call _, nodeHasCall // expression contains a function call
_, nodeLikely // if statement condition likely _, nodeLikely // if statement condition likely
_, nodeHasVal // node.E contains a Val _, nodeHasVal // node.E contains a Val
...@@ -121,7 +120,6 @@ func (n *Node) NonNil() bool { return n.flags&nodeNonNil != 0 } ...@@ -121,7 +120,6 @@ func (n *Node) NonNil() bool { return n.flags&nodeNonNil != 0 }
func (n *Node) Noescape() bool { return n.flags&nodeNoescape != 0 } func (n *Node) Noescape() bool { return n.flags&nodeNoescape != 0 }
func (n *Node) Bounded() bool { return n.flags&nodeBounded != 0 } func (n *Node) Bounded() bool { return n.flags&nodeBounded != 0 }
func (n *Node) Addable() bool { return n.flags&nodeAddable != 0 } func (n *Node) Addable() bool { return n.flags&nodeAddable != 0 }
func (n *Node) Used() bool { return n.flags&nodeUsed != 0 }
func (n *Node) HasCall() bool { return n.flags&nodeHasCall != 0 } func (n *Node) HasCall() bool { return n.flags&nodeHasCall != 0 }
func (n *Node) Likely() bool { return n.flags&nodeLikely != 0 } func (n *Node) Likely() bool { return n.flags&nodeLikely != 0 }
func (n *Node) HasVal() bool { return n.flags&nodeHasVal != 0 } func (n *Node) HasVal() bool { return n.flags&nodeHasVal != 0 }
...@@ -148,7 +146,6 @@ func (n *Node) SetNonNil(b bool) { n.flags.set(nodeNonNil, b) } ...@@ -148,7 +146,6 @@ func (n *Node) SetNonNil(b bool) { n.flags.set(nodeNonNil, b) }
func (n *Node) SetNoescape(b bool) { n.flags.set(nodeNoescape, b) } func (n *Node) SetNoescape(b bool) { n.flags.set(nodeNoescape, b) }
func (n *Node) SetBounded(b bool) { n.flags.set(nodeBounded, b) } func (n *Node) SetBounded(b bool) { n.flags.set(nodeBounded, b) }
func (n *Node) SetAddable(b bool) { n.flags.set(nodeAddable, b) } func (n *Node) SetAddable(b bool) { n.flags.set(nodeAddable, b) }
func (n *Node) SetUsed(b bool) { n.flags.set(nodeUsed, b) }
func (n *Node) SetHasCall(b bool) { n.flags.set(nodeHasCall, b) } func (n *Node) SetHasCall(b bool) { n.flags.set(nodeHasCall, b) }
func (n *Node) SetLikely(b bool) { n.flags.set(nodeLikely, b) } func (n *Node) SetLikely(b bool) { n.flags.set(nodeLikely, b) }
func (n *Node) SetHasVal(b bool) { n.flags.set(nodeHasVal, b) } func (n *Node) SetHasVal(b bool) { n.flags.set(nodeHasVal, b) }
...@@ -231,6 +228,7 @@ type Name struct { ...@@ -231,6 +228,7 @@ type Name struct {
Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one. Vargen int32 // unique name for ONAME within a function. Function outputs are numbered starting at one.
Funcdepth int32 Funcdepth int32
used bool // for variable declared and not used error
flags bitset8 flags bitset8
} }
...@@ -249,6 +247,7 @@ func (n *Name) Byval() bool { return n.flags&nameByval != 0 } ...@@ -249,6 +247,7 @@ func (n *Name) Byval() bool { return n.flags&nameByval != 0 }
func (n *Name) Needzero() bool { return n.flags&nameNeedzero != 0 } func (n *Name) Needzero() bool { return n.flags&nameNeedzero != 0 }
func (n *Name) Keepalive() bool { return n.flags&nameKeepalive != 0 } func (n *Name) Keepalive() bool { return n.flags&nameKeepalive != 0 }
func (n *Name) AutoTemp() bool { return n.flags&nameAutoTemp != 0 } func (n *Name) AutoTemp() bool { return n.flags&nameAutoTemp != 0 }
func (n *Name) Used() bool { return n.used }
func (n *Name) SetCaptured(b bool) { n.flags.set(nameCaptured, b) } func (n *Name) SetCaptured(b bool) { n.flags.set(nameCaptured, b) }
func (n *Name) SetReadonly(b bool) { n.flags.set(nameReadonly, b) } func (n *Name) SetReadonly(b bool) { n.flags.set(nameReadonly, b) }
...@@ -256,6 +255,7 @@ func (n *Name) SetByval(b bool) { n.flags.set(nameByval, b) } ...@@ -256,6 +255,7 @@ func (n *Name) SetByval(b bool) { n.flags.set(nameByval, b) }
func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) } func (n *Name) SetNeedzero(b bool) { n.flags.set(nameNeedzero, b) }
func (n *Name) SetKeepalive(b bool) { n.flags.set(nameKeepalive, b) } func (n *Name) SetKeepalive(b bool) { n.flags.set(nameKeepalive, b) }
func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) } func (n *Name) SetAutoTemp(b bool) { n.flags.set(nameAutoTemp, b) }
func (n *Name) SetUsed(b bool) { n.used = b }
type Param struct { type Param struct {
Ntype *Node Ntype *Node
......
...@@ -323,7 +323,7 @@ OpSwitch: ...@@ -323,7 +323,7 @@ OpSwitch:
return n return n
} }
n.SetUsed(true) n.Name.SetUsed(true)
} }
ok |= Erv ok |= Erv
......
...@@ -461,5 +461,5 @@ func finishUniverse() { ...@@ -461,5 +461,5 @@ func finishUniverse() {
nodfp = newname(lookup(".fp")) nodfp = newname(lookup(".fp"))
nodfp.Type = types.Types[TINT32] nodfp.Type = types.Types[TINT32]
nodfp.SetClass(PPARAM) nodfp.SetClass(PPARAM)
nodfp.SetUsed(true) nodfp.Name.SetUsed(true)
} }
...@@ -37,21 +37,21 @@ func walk(fn *Node) { ...@@ -37,21 +37,21 @@ 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.Name.Used() {
ln.Name.Defn.Left.SetUsed(true) ln.Name.Defn.Left.Name.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.Name.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.Name.Used() {
continue continue
} }
yyerrorl(defn.Left.Pos, "%v declared and not used", ln.Sym) yyerrorl(defn.Left.Pos, "%v declared and not used", ln.Sym)
defn.Left.SetUsed(true) // suppress repeats defn.Left.Name.SetUsed(true) // suppress repeats
} else { } else {
yyerrorl(ln.Pos, "%v declared and not used", ln.Sym) yyerrorl(ln.Pos, "%v declared and not used", ln.Sym)
} }
......
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