nx := ir.Nod(ir.OINDEX, np, ni)
nx.SetBounded(true)
- na := ir.Nod(ir.OADDR, nx, nil)
+ na := nodAddr(nx)
call.PtrList().Append(na)
call.PtrList().Append(nh)
loop.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
hashel := hashfor(f.Type)
call := ir.Nod(ir.OCALL, hashel, nil)
nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
- na := ir.Nod(ir.OADDR, nx, nil)
+ na := nodAddr(nx)
call.PtrList().Append(na)
call.PtrList().Append(nh)
fn.PtrBody().Append(ir.Nod(ir.OAS, nh, call))
hashel := hashmem(f.Type)
call := ir.Nod(ir.OCALL, hashel, nil)
nx := nodSym(ir.OXDOT, np, f.Sym) // TODO: fields from other packages?
- na := ir.Nod(ir.OADDR, nx, nil)
+ na := nodAddr(nx)
call.PtrList().Append(na)
call.PtrList().Append(nh)
call.PtrList().Append(nodintconst(size))
// eqmem returns the node
// memequal(&p.field, &q.field [, size])
func eqmem(p ir.Node, q ir.Node, field *types.Sym, size int64) ir.Node {
- nx := ir.Nod(ir.OADDR, nodSym(ir.OXDOT, p, field), nil)
- ny := ir.Nod(ir.OADDR, nodSym(ir.OXDOT, q, field), nil)
+ nx := nodAddr(nodSym(ir.OXDOT, p, field))
+ ny := nodAddr(nodSym(ir.OXDOT, q, field))
nx = typecheck(nx, ctxExpr)
ny = typecheck(ny, ctxExpr)
v.SetByval(true)
} else {
outermost.Name().SetAddrtaken(true)
- outer = ir.Nod(ir.OADDR, outer, nil)
+ outer = nodAddr(outer)
}
if base.Flag.LowerM > 1 {
v.Heapaddr = addr
var src ir.Node = cr
if v.Byval() {
- src = ir.Nod(ir.OADDR, cr, nil)
+ src = nodAddr(cr)
}
body = append(body, ir.Nod(ir.OAS, addr, src))
}
clos.SetEsc(clo.Esc())
clos.PtrList().Set(append([]ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
- clos = ir.Nod(ir.OADDR, clos, nil)
+ clos = nodAddr(clos)
clos.SetEsc(clo.Esc())
// Force type conversion from *struct to the func type.
body = append(body, ir.Nod(ir.OAS, ptr, cr))
} else {
ptr.SetType(types.NewPtr(rcvrtype))
- body = append(body, ir.Nod(ir.OAS, ptr, ir.Nod(ir.OADDR, cr, nil)))
+ body = append(body, ir.Nod(ir.OAS, ptr, nodAddr(cr)))
}
call := ir.Nod(ir.OCALL, nodSym(ir.OXDOT, ptr, meth), nil)
clos.SetEsc(n.Esc())
clos.PtrList().Set2(ir.Nod(ir.OCFUNC, n.Func().Nname, nil), n.Left())
- clos = ir.Nod(ir.OADDR, clos, nil)
+ clos = nodAddr(clos)
clos.SetEsc(n.Esc())
// Force type conversion from *struct to the func type.
return n
// unary expressions
- case ir.OPLUS, ir.ONEG, ir.OADDR, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
+ case ir.OPLUS, ir.ONEG, ir.OBITNOT, ir.ODEREF, ir.ONOT, ir.ORECV:
return ir.NodAt(r.pos(), op, r.expr(), nil)
+ case ir.OADDR:
+ return nodAddrAt(r.pos(), r.expr())
// binary expressions
case ir.OADD, ir.OAND, ir.OANDAND, ir.OANDNOT, ir.ODIV, ir.OEQ, ir.OGE, ir.OGT, ir.OLE, ir.OLT,
addr.SetType(types.NewPtr(v.Type()))
ia := typecheck(inlvar(addr), ctxExpr)
ninit.Append(ir.Nod(ir.ODCL, ia, nil))
- ninit.Append(typecheck(ir.Nod(ir.OAS, ia, ir.Nod(ir.OADDR, o, nil)), ctxStmt))
+ ninit.Append(typecheck(ir.Nod(ir.OAS, ia, nodAddr(o)), ctxStmt))
inlvars[addr] = ia
// When capturing by reference, all occurrence of the captured var
hp := temp(types.NewPtr(nrange.Type().Elem()))
tmp := ir.Nod(ir.OINDEX, ha, nodintconst(0))
tmp.SetBounded(true)
- init = append(init, ir.Nod(ir.OAS, hp, ir.Nod(ir.OADDR, tmp, nil)))
+ init = append(init, ir.Nod(ir.OAS, hp, nodAddr(tmp)))
// Use OAS2 to correctly handle assignments
// of the form "v1, a[v1] := range".
fn := syslook("mapiterinit")
fn = substArgTypes(fn, t.Key(), t.Elem(), th)
- init = append(init, mkcall1(fn, nil, nil, typename(t), ha, ir.Nod(ir.OADDR, hit, nil)))
+ init = append(init, mkcall1(fn, nil, nil, typename(t), ha, nodAddr(hit)))
nfor.SetLeft(ir.Nod(ir.ONE, nodSym(ir.ODOT, hit, keysym), nodnil()))
fn = syslook("mapiternext")
fn = substArgTypes(fn, th)
- nfor.SetRight(mkcall1(fn, nil, nil, ir.Nod(ir.OADDR, hit, nil)))
+ nfor.SetRight(mkcall1(fn, nil, nil, nodAddr(hit)))
key := nodSym(ir.ODOT, hit, keysym)
key = ir.Nod(ir.ODEREF, key, nil)
tmp := ir.Nod(ir.OINDEX, a, nodintconst(0))
tmp.SetBounded(true)
- tmp = ir.Nod(ir.OADDR, tmp, nil)
+ tmp = nodAddr(tmp)
tmp = convnop(tmp, types.Types[types.TUNSAFEPTR])
n.PtrBody().Append(ir.Nod(ir.OAS, hp, tmp))
s.Def = n
}
- n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
+ n := nodAddr(ir.AsNode(s.Def))
n.SetType(types.NewPtr(s.Def.Type()))
n.SetTypecheck(1)
return n
itabs = append(itabs, itabEntry{t: t, itype: itype, lsym: s.Linksym()})
}
- n := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
+ n := nodAddr(ir.AsNode(s.Def))
n.SetType(types.NewPtr(s.Def.Type()))
n.SetTypecheck(1)
return n
x.SetTypecheck(1)
s.Def = x
}
- z := ir.Nod(ir.OADDR, ir.AsNode(s.Def), nil)
+ z := nodAddr(ir.AsNode(s.Def))
z.SetType(types.NewPtr(types.Types[types.TUINT8]))
z.SetTypecheck(1)
return z
switch n.Op() {
case ir.OSEND:
- n.SetRight(ir.Nod(ir.OADDR, n.Right(), nil))
+ n.SetRight(nodAddr(n.Right()))
n.SetRight(typecheck(n.Right(), ctxExpr))
case ir.OSELRECV:
if !ir.IsBlank(n.Left()) {
- n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil))
+ n.SetLeft(nodAddr(n.Left()))
n.SetLeft(typecheck(n.Left(), ctxExpr))
}
case ir.OSELRECV2:
if !ir.IsBlank(n.List().First()) {
- n.List().SetIndex(0, ir.Nod(ir.OADDR, n.List().First(), nil))
+ n.List().SetIndex(0, nodAddr(n.List().First()))
n.List().SetIndex(0, typecheck(n.List().First(), ctxExpr))
}
}
if ir.IsBlank(elem) {
elem = nodnil()
}
- receivedp := ir.Nod(ir.OADDR, n.List().Second(), nil)
+ receivedp := nodAddr(n.List().Second())
receivedp = typecheck(receivedp, ctxExpr)
call = mkcall1(chanfn("selectnbrecv2", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), elem, receivedp, ch)
}
var pc0, pcs ir.Node
if base.Flag.Race {
pcs = temp(types.NewArray(types.Types[types.TUINTPTR], int64(ncas)))
- pc0 = typecheck(ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, pcs, nodintconst(0)), nil), ctxExpr)
+ pc0 = typecheck(nodAddr(ir.Nod(ir.OINDEX, pcs, nodintconst(0))), ctxExpr)
} else {
pc0 = nodnil()
}
// TODO(mdempsky): There should be a cleaner way to
// handle this.
if base.Flag.Race {
- r = mkcall("selectsetpc", nil, nil, ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, pcs, nodintconst(int64(i))), nil))
+ r = mkcall("selectsetpc", nil, nil, nodAddr(ir.Nod(ir.OINDEX, pcs, nodintconst(int64(i)))))
init = append(init, r)
}
}
// bytePtrToIndex returns a Node representing "(*byte)(&n[i])".
func bytePtrToIndex(n ir.Node, i int64) ir.Node {
- s := ir.Nod(ir.OADDR, ir.Nod(ir.OINDEX, n, nodintconst(i)), nil)
+ s := nodAddr(ir.Nod(ir.OINDEX, n, nodintconst(i)))
t := types.NewPtr(types.Types[types.TUINT8])
return convnop(s, t)
}
init.Append(ir.Nod(ir.OVARDEF, x, nil))
}
- a = ir.Nod(ir.OADDR, x, nil)
+ a = nodAddr(x)
} else if n.Esc() == EscNone {
a = temp(t)
if vstat == nil {
init.Append(ir.Nod(ir.OVARDEF, a, nil))
}
- a = ir.Nod(ir.OADDR, a, nil)
+ a = nodAddr(a)
} else {
a = ir.Nod(ir.ONEW, ir.TypeNode(t), nil)
}
if n.Right() != nil {
// n.Right is stack temporary used as backing store.
init.Append(ir.Nod(ir.OAS, n.Right(), nil)) // zero backing store, just in case (#18410)
- r = ir.Nod(ir.OADDR, n.Right(), nil)
+ r = nodAddr(n.Right())
r = typecheck(r, ctxExpr)
} else {
r = ir.Nod(ir.ONEW, ir.TypeNode(n.Left().Type()), nil)
}
}
+// nodAddr returns a node representing &n.
+func nodAddr(n ir.Node) ir.Node {
+ return ir.Nod(ir.OADDR, n, nil)
+}
+func nodAddrAt(pos src.XPos, n ir.Node) ir.Node {
+ return ir.NodAt(pos, ir.OADDR, n, nil)
+}
+
// newname returns a new ONAME Node associated with symbol s.
func NewName(s *types.Sym) *ir.Name {
n := ir.NewNameAt(base.Pos, s)
dot = dot.Left() // skip final .M
// TODO(mdempsky): Remove dependency on dotlist.
if !dotlist[0].field.Type.IsPtr() {
- dot = ir.Nod(ir.OADDR, dot, nil)
+ dot = nodAddr(dot)
}
as := ir.Nod(ir.OAS, nthis, convnop(dot, rcvr))
fn.PtrBody().Append(as)
return n
}
- n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil))
+ n.SetLeft(nodAddr(n.Left()))
n.Left().SetImplicit(true)
n.SetLeft(typecheck(n.Left(), ctxExpr))
l = n.Left()
if !types.Identical(rcvr, tt) {
if rcvr.IsPtr() && types.Identical(rcvr.Elem(), tt) {
checklvalue(n.Left(), "call pointer method on")
- n.SetLeft(ir.Nod(ir.OADDR, n.Left(), nil))
+ n.SetLeft(nodAddr(n.Left()))
n.Left().SetImplicit(true)
n.SetLeft(typecheck(n.Left(), ctxType|ctxExpr))
} else if tt.IsPtr() && (!rcvr.IsPtr() || rcvr.IsPtr() && rcvr.Elem().NotInHeap()) && types.Identical(tt.Elem(), rcvr) {
// For *T, return &T{...}.
n.SetRight(ir.TypeNode(t.Elem()))
- n = ir.NodAt(n.Pos(), ir.OADDR, n, nil)
+ n = nodAddrAt(n.Pos(), n)
n.SetImplicit(true)
}
return mkcall("gopanic", nil, init, n.Left())
case ir.ORECOVER:
- return mkcall("gorecover", n.Type(), init, ir.Nod(ir.OADDR, nodfp, nil))
+ return mkcall("gorecover", n.Type(), init, nodAddr(nodfp))
case ir.OCLOSUREREAD, ir.OCFUNC:
return n
// order.stmt made sure x is addressable.
n.Right().SetLeft(walkexpr(n.Right().Left(), init))
- n1 := ir.Nod(ir.OADDR, n.Left(), nil)
+ n1 := nodAddr(n.Left())
r := n.Right().Left() // the channel
return mkcall1(chanfn("chanrecv1", 2, r.Type()), nil, init, r, n1)
if ir.IsBlank(n.List().First()) {
n1 = nodnil()
} else {
- n1 = ir.Nod(ir.OADDR, n.List().First(), nil)
+ n1 = nodAddr(n.List().First())
}
fn := chanfn("chanrecv2", 2, r.Left().Type())
ok := n.List().Second()
} else {
// standard version takes key by reference
// order.expr made sure key is addressable.
- key = ir.Nod(ir.OADDR, r.Right(), nil)
+ key = nodAddr(r.Right())
}
// from:
fast := mapfast(t)
if fast == mapslow {
// order.stmt made sure key is addressable.
- key = ir.Nod(ir.OADDR, key, nil)
+ key = nodAddr(key)
}
return mkcall1(mapfndel(mapdelete[fast], t), nil, init, typename(t), map_, key)
if value != nil {
// Value is identical to n.Left.
// Construct the interface directly: {type/itab, &value}.
- l := ir.Nod(ir.OEFACE, typeword(), typecheck(ir.Nod(ir.OADDR, value, nil), ctxExpr))
+ l := ir.Nod(ir.OEFACE, typeword(), typecheck(nodAddr(value), ctxExpr))
l.SetType(toType)
l.SetTypecheck(n.Typecheck())
return l
if !islvalue(v) {
v = copyexpr(v, v.Type(), init)
}
- v = ir.Nod(ir.OADDR, v, nil)
+ v = nodAddr(v)
}
dowidth(fromType)
if fast == mapslow {
// standard version takes key by reference.
// order.expr made sure key is addressable.
- key = ir.Nod(ir.OADDR, key, nil)
+ key = nodAddr(key)
}
n = mkcall1(mapfn(mapassign[fast], t), nil, init, typename(t), map_, key)
} else {
if fast == mapslow {
// standard version takes key by reference.
// order.expr made sure key is addressable.
- key = ir.Nod(ir.OADDR, key, nil)
+ key = nodAddr(key)
}
if w := t.Elem().Width; w <= zeroValSize {
r = ir.Nod(ir.OAS, r, nil) // zero temp
r = typecheck(r, ctxStmt)
init.Append(r)
- r = ir.Nod(ir.OADDR, r.Left(), nil)
+ r = nodAddr(r.Left())
return typecheck(r, ctxExpr)
}
return callnew(n.Type().Elem())
zero = typecheck(zero, ctxStmt)
init.Append(zero)
// h = &hv
- h = ir.Nod(ir.OADDR, hv, nil)
+ h = nodAddr(hv)
// Allocate one bucket pointed to by hmap.buckets on stack if hint
// is not larger than BUCKETSIZE. In case hint is larger than
nif.PtrBody().Append(zero)
// b = &bv
- b := ir.Nod(ir.OADDR, bv, nil)
+ b := nodAddr(bv)
// h.buckets = b
bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
a := nodnil()
if n.Esc() == EscNone {
t := types.NewArray(types.Types[types.TUINT8], 4)
- a = ir.Nod(ir.OADDR, temp(t), nil)
+ a = nodAddr(temp(t))
}
// intstring(*[4]byte, rune)
return mkcall("intstring", n.Type(), init, a, conv(n.Left(), types.Types[types.TINT64]))
if n.Esc() == EscNone {
// Create temporary buffer for string on stack.
t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
- a = ir.Nod(ir.OADDR, temp(t), nil)
+ a = nodAddr(temp(t))
}
if n.Op() == ir.ORUNES2STR {
// slicerunetostring(*[32]byte, []rune) string
t := types.NewArray(types.Types[types.TUINT8], int64(len(sc)))
var a ir.Node
if n.Esc() == EscNone && len(sc) <= int(maxImplicitStackVarSize) {
- a = ir.Nod(ir.OADDR, temp(t), nil)
+ a = nodAddr(temp(t))
} else {
a = callnew(t)
}
if n.Esc() == EscNone {
// Create temporary buffer for slice on stack.
t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
- a = ir.Nod(ir.OADDR, temp(t), nil)
+ a = nodAddr(temp(t))
}
// stringtoslicebyte(*32[byte], string) []byte
return mkcall("stringtoslicebyte", n.Type(), init, a, conv(s, types.Types[types.TSTRING]))
if n.Esc() == EscNone {
// Create temporary buffer for slice on stack.
t := types.NewArray(types.Types[types.TINT32], tmpstringbufsize)
- a = ir.Nod(ir.OADDR, temp(t), nil)
+ a = nodAddr(temp(t))
}
// stringtoslicerune(*[32]rune, string) []rune
return mkcall("stringtoslicerune", n.Type(), init, a, conv(n.Left(), types.Types[types.TSTRING]))
n1 := n.Right()
n1 = assignconv(n1, n.Left().Type().Elem(), "chan send")
n1 = walkexpr(n1, init)
- n1 = ir.Nod(ir.OADDR, n1, nil)
+ n1 = nodAddr(n1)
return mkcall1(chanfn("chansend1", 2, n.Left().Type()), nil, init, n.Left(), n1)
case ir.OCLOSURE:
if sz < tmpstringbufsize {
// Create temporary buffer for result string on stack.
t := types.NewArray(types.Types[types.TUINT8], tmpstringbufsize)
- buf = ir.Nod(ir.OADDR, temp(t), nil)
+ buf = nodAddr(temp(t))
}
}
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
nptr1.SetBounded(true)
- nptr1 = ir.Nod(ir.OADDR, nptr1, nil)
+ nptr1 = nodAddr(nptr1)
nptr2 := ir.Nod(ir.OSPTR, l2, nil)
// hp := &s[len(l1)]
hp := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
hp.SetBounded(true)
- hp = ir.Nod(ir.OADDR, hp, nil)
+ hp = nodAddr(hp)
hp = convnop(hp, types.Types[types.TUNSAFEPTR])
// hn := l2 * sizeof(elem(s))
fn, needsize := eqfor(t)
call := ir.Nod(ir.OCALL, fn, nil)
- call.PtrList().Append(ir.Nod(ir.OADDR, cmpl, nil))
- call.PtrList().Append(ir.Nod(ir.OADDR, cmpr, nil))
+ call.PtrList().Append(nodAddr(cmpl))
+ call.PtrList().Append(nodAddr(cmpr))
if needsize {
call.PtrList().Append(nodintconst(t.Width))
}