mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.regabi] cmd/compile: cleanup preparing for concrete types, 2
Avoid using the same variable for two different concrete Node types in other files (beyond walk). This will smooth the introduction of specific constructors, replacing ir.Nod and friends. Passes buildall w/ toolstash -cmp. Replay of CL 275885, lost to the bad-merge history rewrite. Change-Id: I0da89502a0bd636b8766f01b6f843c7821b3e9ab Reviewed-on: https://go-review.googlesource.com/c/go/+/277955 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
fa06894b36
commit
5ae70b85c6
11 changed files with 126 additions and 191 deletions
|
|
@ -819,12 +819,12 @@ func eqstring(s, t ir.Node) (eqlen, eqmem ir.Node) {
|
||||||
fn = substArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8])
|
fn = substArgTypes(fn, types.Types[types.TUINT8], types.Types[types.TUINT8])
|
||||||
call := ir.Nod(ir.OCALL, fn, nil)
|
call := ir.Nod(ir.OCALL, fn, nil)
|
||||||
call.PtrList().Append(sptr, tptr, ir.Copy(slen))
|
call.PtrList().Append(sptr, tptr, ir.Copy(slen))
|
||||||
call = typecheck(call, ctxExpr|ctxMultiOK)
|
call1 := typecheck(call, ctxExpr|ctxMultiOK)
|
||||||
|
|
||||||
cmp := ir.Nod(ir.OEQ, slen, tlen)
|
cmp := ir.Nod(ir.OEQ, slen, tlen)
|
||||||
cmp = typecheck(cmp, ctxExpr)
|
cmp1 := typecheck(cmp, ctxExpr)
|
||||||
cmp.SetType(types.Types[types.TBOOL])
|
cmp.SetType(types.Types[types.TBOOL])
|
||||||
return cmp, call
|
return cmp1, call1
|
||||||
}
|
}
|
||||||
|
|
||||||
// eqinterface returns the nodes
|
// eqinterface returns the nodes
|
||||||
|
|
@ -857,21 +857,19 @@ func eqinterface(s, t ir.Node) (eqtab, eqdata ir.Node) {
|
||||||
|
|
||||||
call := ir.Nod(ir.OCALL, fn, nil)
|
call := ir.Nod(ir.OCALL, fn, nil)
|
||||||
call.PtrList().Append(stab, sdata, tdata)
|
call.PtrList().Append(stab, sdata, tdata)
|
||||||
call = typecheck(call, ctxExpr|ctxMultiOK)
|
call1 := typecheck(call, ctxExpr|ctxMultiOK)
|
||||||
|
|
||||||
cmp := ir.Nod(ir.OEQ, stab, ttab)
|
cmp := ir.Nod(ir.OEQ, stab, ttab)
|
||||||
cmp = typecheck(cmp, ctxExpr)
|
cmp1 := typecheck(cmp, ctxExpr)
|
||||||
cmp.SetType(types.Types[types.TBOOL])
|
cmp1.SetType(types.Types[types.TBOOL])
|
||||||
return cmp, call
|
return cmp1, call1
|
||||||
}
|
}
|
||||||
|
|
||||||
// eqmem returns the node
|
// eqmem returns the node
|
||||||
// memequal(&p.field, &q.field [, size])
|
// memequal(&p.field, &q.field [, size])
|
||||||
func eqmem(p ir.Node, q ir.Node, field *types.Sym, size int64) ir.Node {
|
func eqmem(p ir.Node, q ir.Node, field *types.Sym, size int64) ir.Node {
|
||||||
nx := nodAddr(nodSym(ir.OXDOT, p, field))
|
nx := typecheck(nodAddr(nodSym(ir.OXDOT, p, field)), ctxExpr)
|
||||||
ny := nodAddr(nodSym(ir.OXDOT, q, field))
|
ny := typecheck(nodAddr(nodSym(ir.OXDOT, q, field)), ctxExpr)
|
||||||
nx = typecheck(nx, ctxExpr)
|
|
||||||
ny = typecheck(ny, ctxExpr)
|
|
||||||
|
|
||||||
fn, needsize := eqmemfunc(size, nx.Type().Elem())
|
fn, needsize := eqmemfunc(size, nx.Type().Elem())
|
||||||
call := ir.Nod(ir.OCALL, fn, nil)
|
call := ir.Nod(ir.OCALL, fn, nil)
|
||||||
|
|
|
||||||
|
|
@ -396,22 +396,22 @@ func walkclosure(clo ir.Node, init *ir.Nodes) ir.Node {
|
||||||
clos.SetEsc(clo.Esc())
|
clos.SetEsc(clo.Esc())
|
||||||
clos.PtrList().Set(append([]ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
|
clos.PtrList().Set(append([]ir.Node{ir.Nod(ir.OCFUNC, fn.Nname, nil)}, fn.ClosureEnter.Slice()...))
|
||||||
|
|
||||||
clos = nodAddr(clos)
|
addr := nodAddr(clos)
|
||||||
clos.SetEsc(clo.Esc())
|
addr.SetEsc(clo.Esc())
|
||||||
|
|
||||||
// Force type conversion from *struct to the func type.
|
// Force type conversion from *struct to the func type.
|
||||||
clos = convnop(clos, clo.Type())
|
cfn := convnop(addr, clo.Type())
|
||||||
|
|
||||||
// non-escaping temp to use, if any.
|
// non-escaping temp to use, if any.
|
||||||
if x := prealloc[clo]; x != nil {
|
if x := prealloc[clo]; x != nil {
|
||||||
if !types.Identical(typ, x.Type()) {
|
if !types.Identical(typ, x.Type()) {
|
||||||
panic("closure type does not match order's assigned type")
|
panic("closure type does not match order's assigned type")
|
||||||
}
|
}
|
||||||
clos.Left().SetRight(x)
|
addr.SetRight(x)
|
||||||
delete(prealloc, clo)
|
delete(prealloc, clo)
|
||||||
}
|
}
|
||||||
|
|
||||||
return walkexpr(clos, init)
|
return walkexpr(cfn, init)
|
||||||
}
|
}
|
||||||
|
|
||||||
func typecheckpartialcall(dot ir.Node, sym *types.Sym) *ir.CallPartExpr {
|
func typecheckpartialcall(dot ir.Node, sym *types.Sym) *ir.CallPartExpr {
|
||||||
|
|
@ -482,11 +482,12 @@ func makepartialcall(dot ir.Node, t0 *types.Type, meth *types.Sym) *ir.Func {
|
||||||
call.PtrList().Set(paramNnames(tfn.Type()))
|
call.PtrList().Set(paramNnames(tfn.Type()))
|
||||||
call.SetIsDDD(tfn.Type().IsVariadic())
|
call.SetIsDDD(tfn.Type().IsVariadic())
|
||||||
if t0.NumResults() != 0 {
|
if t0.NumResults() != 0 {
|
||||||
n := ir.Nod(ir.ORETURN, nil, nil)
|
ret := ir.Nod(ir.ORETURN, nil, nil)
|
||||||
n.PtrList().Set1(call)
|
ret.PtrList().Set1(call)
|
||||||
call = n
|
body = append(body, ret)
|
||||||
|
} else {
|
||||||
|
body = append(body, call)
|
||||||
}
|
}
|
||||||
body = append(body, call)
|
|
||||||
|
|
||||||
fn.PtrBody().Set(body)
|
fn.PtrBody().Set(body)
|
||||||
funcbody()
|
funcbody()
|
||||||
|
|
@ -530,8 +531,7 @@ func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node {
|
||||||
n.SetLeft(cheapexpr(n.Left(), init))
|
n.SetLeft(cheapexpr(n.Left(), init))
|
||||||
n.SetLeft(walkexpr(n.Left(), nil))
|
n.SetLeft(walkexpr(n.Left(), nil))
|
||||||
|
|
||||||
tab := ir.Nod(ir.OITAB, n.Left(), nil)
|
tab := typecheck(ir.Nod(ir.OITAB, n.Left(), nil), ctxExpr)
|
||||||
tab = typecheck(tab, ctxExpr)
|
|
||||||
|
|
||||||
c := ir.Nod(ir.OCHECKNIL, tab, nil)
|
c := ir.Nod(ir.OCHECKNIL, tab, nil)
|
||||||
c.SetTypecheck(1)
|
c.SetTypecheck(1)
|
||||||
|
|
@ -544,22 +544,22 @@ func walkpartialcall(n *ir.CallPartExpr, init *ir.Nodes) ir.Node {
|
||||||
clos.SetEsc(n.Esc())
|
clos.SetEsc(n.Esc())
|
||||||
clos.PtrList().Set2(ir.Nod(ir.OCFUNC, n.Func().Nname, nil), n.Left())
|
clos.PtrList().Set2(ir.Nod(ir.OCFUNC, n.Func().Nname, nil), n.Left())
|
||||||
|
|
||||||
clos = nodAddr(clos)
|
addr := nodAddr(clos)
|
||||||
clos.SetEsc(n.Esc())
|
addr.SetEsc(n.Esc())
|
||||||
|
|
||||||
// Force type conversion from *struct to the func type.
|
// Force type conversion from *struct to the func type.
|
||||||
clos = convnop(clos, n.Type())
|
cfn := convnop(addr, n.Type())
|
||||||
|
|
||||||
// non-escaping temp to use, if any.
|
// non-escaping temp to use, if any.
|
||||||
if x := prealloc[n]; x != nil {
|
if x := prealloc[n]; x != nil {
|
||||||
if !types.Identical(typ, x.Type()) {
|
if !types.Identical(typ, x.Type()) {
|
||||||
panic("partial call type does not match order's assigned type")
|
panic("partial call type does not match order's assigned type")
|
||||||
}
|
}
|
||||||
clos.Left().SetRight(x)
|
addr.SetRight(x)
|
||||||
delete(prealloc, n)
|
delete(prealloc, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
return walkexpr(clos, init)
|
return walkexpr(cfn, init)
|
||||||
}
|
}
|
||||||
|
|
||||||
// callpartMethod returns the *types.Field representing the method
|
// callpartMethod returns the *types.Field representing the method
|
||||||
|
|
|
||||||
|
|
@ -1005,13 +1005,11 @@ func mkinlcall(n ir.Node, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
if as.Rlist().Len() != 0 {
|
if as.Rlist().Len() != 0 {
|
||||||
as = typecheck(as, ctxStmt)
|
ninit.Append(typecheck(as, ctxStmt))
|
||||||
ninit.Append(as)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if vas != nil {
|
if vas != nil {
|
||||||
vas = typecheck(vas, ctxStmt)
|
ninit.Append(typecheck(vas, ctxStmt))
|
||||||
ninit.Append(vas)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !delayretvars {
|
if !delayretvars {
|
||||||
|
|
@ -1019,8 +1017,7 @@ func mkinlcall(n ir.Node, fn *ir.Func, maxCost int32, inlMap map[*ir.Func]bool,
|
||||||
for _, n := range retvars {
|
for _, n := range retvars {
|
||||||
ninit.Append(ir.Nod(ir.ODCL, n, nil))
|
ninit.Append(ir.Nod(ir.ODCL, n, nil))
|
||||||
ras := ir.Nod(ir.OAS, n, nil)
|
ras := ir.Nod(ir.OAS, n, nil)
|
||||||
ras = typecheck(ras, ctxStmt)
|
ninit.Append(typecheck(ras, ctxStmt))
|
||||||
ninit.Append(ras)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1235,8 +1232,7 @@ func (subst *inlsubst) node(n ir.Node) ir.Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
as = typecheck(as, ctxStmt)
|
init = append(init, typecheck(as, ctxStmt))
|
||||||
init = append(init, as)
|
|
||||||
}
|
}
|
||||||
init = append(init, nodSym(ir.OGOTO, nil, subst.retlabel))
|
init = append(init, nodSym(ir.OGOTO, nil, subst.retlabel))
|
||||||
typecheckslice(init, ctxStmt)
|
typecheckslice(init, ctxStmt)
|
||||||
|
|
@ -1310,10 +1306,9 @@ func devirtualizeCall(call ir.Node) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
x := ir.NodAt(call.Left().Pos(), ir.ODOTTYPE, call.Left().Left(), nil)
|
dt := ir.NodAt(call.Left().Pos(), ir.ODOTTYPE, call.Left().Left(), nil)
|
||||||
x.SetType(typ)
|
dt.SetType(typ)
|
||||||
x = nodlSym(call.Left().Pos(), ir.OXDOT, x, call.Left().Sym())
|
x := typecheck(nodlSym(call.Left().Pos(), ir.OXDOT, dt, call.Left().Sym()), ctxExpr|ctxCallee)
|
||||||
x = typecheck(x, ctxExpr|ctxCallee)
|
|
||||||
switch x.Op() {
|
switch x.Op() {
|
||||||
case ir.ODOTMETH:
|
case ir.ODOTMETH:
|
||||||
if base.Flag.LowerM != 0 {
|
if base.Flag.LowerM != 0 {
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,11 @@ func order(fn *ir.Func) {
|
||||||
orderBlock(fn.PtrBody(), map[string][]*ir.Name{})
|
orderBlock(fn.PtrBody(), map[string][]*ir.Name{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// append typechecks stmt and appends it to out.
|
||||||
|
func (o *Order) append(stmt ir.Node) {
|
||||||
|
o.out = append(o.out, typecheck(stmt, ctxStmt))
|
||||||
|
}
|
||||||
|
|
||||||
// newTemp allocates a new temporary with the given type,
|
// newTemp allocates a new temporary with the given type,
|
||||||
// pushes it onto the temp stack, and returns it.
|
// pushes it onto the temp stack, and returns it.
|
||||||
// If clear is true, newTemp emits code to zero the temporary.
|
// If clear is true, newTemp emits code to zero the temporary.
|
||||||
|
|
@ -82,9 +87,7 @@ func (o *Order) newTemp(t *types.Type, clear bool) *ir.Name {
|
||||||
v = temp(t)
|
v = temp(t)
|
||||||
}
|
}
|
||||||
if clear {
|
if clear {
|
||||||
a := ir.Nod(ir.OAS, v, nil)
|
o.append(ir.Nod(ir.OAS, v, nil))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
o.out = append(o.out, a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
o.temp = append(o.temp, v)
|
o.temp = append(o.temp, v)
|
||||||
|
|
@ -114,9 +117,7 @@ func (o *Order) copyExprClear(n ir.Node) *ir.Name {
|
||||||
func (o *Order) copyExpr1(n ir.Node, clear bool) *ir.Name {
|
func (o *Order) copyExpr1(n ir.Node, clear bool) *ir.Name {
|
||||||
t := n.Type()
|
t := n.Type()
|
||||||
v := o.newTemp(t, clear)
|
v := o.newTemp(t, clear)
|
||||||
a := ir.Nod(ir.OAS, v, n)
|
o.append(ir.Nod(ir.OAS, v, n))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
o.out = append(o.out, a)
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -306,9 +307,7 @@ func (o *Order) cleanTempNoPop(mark ordermarker) []ir.Node {
|
||||||
var out []ir.Node
|
var out []ir.Node
|
||||||
for i := len(o.temp) - 1; i >= int(mark); i-- {
|
for i := len(o.temp) - 1; i >= int(mark); i-- {
|
||||||
n := o.temp[i]
|
n := o.temp[i]
|
||||||
kill := ir.Nod(ir.OVARKILL, n, nil)
|
out = append(out, typecheck(ir.Nod(ir.OVARKILL, n, nil), ctxStmt))
|
||||||
kill = typecheck(kill, ctxStmt)
|
|
||||||
out = append(out, kill)
|
|
||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
@ -407,9 +406,7 @@ func (o *Order) edge() {
|
||||||
// counter += 1
|
// counter += 1
|
||||||
incr := ir.Nod(ir.OASOP, counter, nodintconst(1))
|
incr := ir.Nod(ir.OASOP, counter, nodintconst(1))
|
||||||
incr.SetSubOp(ir.OADD)
|
incr.SetSubOp(ir.OADD)
|
||||||
incr = typecheck(incr, ctxStmt)
|
o.append(incr)
|
||||||
|
|
||||||
o.out = append(o.out, incr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// orderBlock orders the block of statements in n into a new slice,
|
// orderBlock orders the block of statements in n into a new slice,
|
||||||
|
|
@ -570,8 +567,7 @@ func (o *Order) mapAssign(n ir.Node) {
|
||||||
t := o.newTemp(m.Type(), false)
|
t := o.newTemp(m.Type(), false)
|
||||||
n.List().SetIndex(i, t)
|
n.List().SetIndex(i, t)
|
||||||
a := ir.Nod(ir.OAS, m, t)
|
a := ir.Nod(ir.OAS, m, t)
|
||||||
a = typecheck(a, ctxStmt)
|
post = append(post, typecheck(a, ctxStmt))
|
||||||
post = append(post, a)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -918,27 +914,23 @@ func (o *Order) stmt(n ir.Node) {
|
||||||
// the conversion happens in the OAS instead.
|
// the conversion happens in the OAS instead.
|
||||||
if r.Colas() {
|
if r.Colas() {
|
||||||
dcl := ir.Nod(ir.ODCL, dst, nil)
|
dcl := ir.Nod(ir.ODCL, dst, nil)
|
||||||
dcl = typecheck(dcl, ctxStmt)
|
n2.PtrInit().Append(typecheck(dcl, ctxStmt))
|
||||||
n2.PtrInit().Append(dcl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp := o.newTemp(recv.Left().Type().Elem(), recv.Left().Type().Elem().HasPointers())
|
tmp := o.newTemp(recv.Left().Type().Elem(), recv.Left().Type().Elem().HasPointers())
|
||||||
as := ir.Nod(ir.OAS, dst, tmp)
|
as := ir.Nod(ir.OAS, dst, tmp)
|
||||||
as = typecheck(as, ctxStmt)
|
n2.PtrInit().Append(typecheck(as, ctxStmt))
|
||||||
n2.PtrInit().Append(as)
|
|
||||||
dst = tmp
|
dst = tmp
|
||||||
}
|
}
|
||||||
if !ir.IsBlank(ok) {
|
if !ir.IsBlank(ok) {
|
||||||
if r.Colas() {
|
if r.Colas() {
|
||||||
dcl := ir.Nod(ir.ODCL, ok, nil)
|
dcl := ir.Nod(ir.ODCL, ok, nil)
|
||||||
dcl = typecheck(dcl, ctxStmt)
|
n2.PtrInit().Append(typecheck(dcl, ctxStmt))
|
||||||
n2.PtrInit().Append(dcl)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp := o.newTemp(types.Types[types.TBOOL], false)
|
tmp := o.newTemp(types.Types[types.TBOOL], false)
|
||||||
as := ir.Nod(ir.OAS, ok, conv(tmp, ok.Type()))
|
as := ir.Nod(ir.OAS, ok, conv(tmp, ok.Type()))
|
||||||
as = typecheck(as, ctxStmt)
|
n2.PtrInit().Append(typecheck(as, ctxStmt))
|
||||||
n2.PtrInit().Append(as)
|
|
||||||
ok = tmp
|
ok = tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1408,8 +1400,7 @@ func (o *Order) as2(n ir.Node) {
|
||||||
as := ir.Nod(ir.OAS2, nil, nil)
|
as := ir.Nod(ir.OAS2, nil, nil)
|
||||||
as.PtrList().Set(left)
|
as.PtrList().Set(left)
|
||||||
as.PtrRlist().Set(tmplist)
|
as.PtrRlist().Set(tmplist)
|
||||||
as = typecheck(as, ctxStmt)
|
o.stmt(typecheck(as, ctxStmt))
|
||||||
o.stmt(as)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// okAs2 orders OAS2XXX with ok.
|
// okAs2 orders OAS2XXX with ok.
|
||||||
|
|
@ -1429,14 +1420,12 @@ func (o *Order) okAs2(n ir.Node) {
|
||||||
|
|
||||||
if tmp1 != nil {
|
if tmp1 != nil {
|
||||||
r := ir.Nod(ir.OAS, n.List().First(), tmp1)
|
r := ir.Nod(ir.OAS, n.List().First(), tmp1)
|
||||||
r = typecheck(r, ctxStmt)
|
o.mapAssign(typecheck(r, ctxStmt))
|
||||||
o.mapAssign(r)
|
|
||||||
n.List().SetFirst(tmp1)
|
n.List().SetFirst(tmp1)
|
||||||
}
|
}
|
||||||
if tmp2 != nil {
|
if tmp2 != nil {
|
||||||
r := ir.Nod(ir.OAS, n.List().Second(), conv(tmp2, n.List().Second().Type()))
|
r := ir.Nod(ir.OAS, n.List().Second(), conv(tmp2, n.List().Second().Type()))
|
||||||
r = typecheck(r, ctxStmt)
|
o.mapAssign(typecheck(r, ctxStmt))
|
||||||
o.mapAssign(r)
|
|
||||||
n.List().SetSecond(tmp2)
|
n.List().SetSecond(tmp2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -288,9 +288,8 @@ func walkrange(nrange ir.Node) ir.Node {
|
||||||
// This runs *after* the condition check, so we know
|
// This runs *after* the condition check, so we know
|
||||||
// advancing the pointer is safe and won't go past the
|
// advancing the pointer is safe and won't go past the
|
||||||
// end of the allocation.
|
// end of the allocation.
|
||||||
a = ir.Nod(ir.OAS, hp, addptr(hp, t.Elem().Width))
|
as := ir.Nod(ir.OAS, hp, addptr(hp, t.Elem().Width))
|
||||||
a = typecheck(a, ctxStmt)
|
nfor.PtrList().Set1(typecheck(as, ctxStmt))
|
||||||
nfor.PtrList().Set1(a)
|
|
||||||
|
|
||||||
case types.TMAP:
|
case types.TMAP:
|
||||||
// order.stmt allocated the iterator for us.
|
// order.stmt allocated the iterator for us.
|
||||||
|
|
@ -312,15 +311,13 @@ func walkrange(nrange ir.Node) ir.Node {
|
||||||
fn = substArgTypes(fn, th)
|
fn = substArgTypes(fn, th)
|
||||||
nfor.SetRight(mkcall1(fn, nil, nil, nodAddr(hit)))
|
nfor.SetRight(mkcall1(fn, nil, nil, nodAddr(hit)))
|
||||||
|
|
||||||
key := nodSym(ir.ODOT, hit, keysym)
|
key := ir.Nod(ir.ODEREF, nodSym(ir.ODOT, hit, keysym), nil)
|
||||||
key = ir.Nod(ir.ODEREF, key, nil)
|
|
||||||
if v1 == nil {
|
if v1 == nil {
|
||||||
body = nil
|
body = nil
|
||||||
} else if v2 == nil {
|
} else if v2 == nil {
|
||||||
body = []ir.Node{ir.Nod(ir.OAS, v1, key)}
|
body = []ir.Node{ir.Nod(ir.OAS, v1, key)}
|
||||||
} else {
|
} else {
|
||||||
elem := nodSym(ir.ODOT, hit, elemsym)
|
elem := ir.Nod(ir.ODEREF, nodSym(ir.ODOT, hit, elemsym), nil)
|
||||||
elem = ir.Nod(ir.ODEREF, elem, nil)
|
|
||||||
a := ir.Nod(ir.OAS2, nil, nil)
|
a := ir.Nod(ir.OAS2, nil, nil)
|
||||||
a.PtrList().Set2(v1, v2)
|
a.PtrList().Set2(v1, v2)
|
||||||
a.PtrRlist().Set2(key, elem)
|
a.PtrRlist().Set2(key, elem)
|
||||||
|
|
@ -570,19 +567,15 @@ func arrayClear(loop, v1, v2, a ir.Node) ir.Node {
|
||||||
// hp = &a[0]
|
// hp = &a[0]
|
||||||
hp := temp(types.Types[types.TUNSAFEPTR])
|
hp := temp(types.Types[types.TUNSAFEPTR])
|
||||||
|
|
||||||
tmp := ir.Nod(ir.OINDEX, a, nodintconst(0))
|
ix := ir.Nod(ir.OINDEX, a, nodintconst(0))
|
||||||
tmp.SetBounded(true)
|
ix.SetBounded(true)
|
||||||
tmp = nodAddr(tmp)
|
addr := convnop(nodAddr(ix), types.Types[types.TUNSAFEPTR])
|
||||||
tmp = convnop(tmp, types.Types[types.TUNSAFEPTR])
|
n.PtrBody().Append(ir.Nod(ir.OAS, hp, addr))
|
||||||
n.PtrBody().Append(ir.Nod(ir.OAS, hp, tmp))
|
|
||||||
|
|
||||||
// hn = len(a) * sizeof(elem(a))
|
// hn = len(a) * sizeof(elem(a))
|
||||||
hn := temp(types.Types[types.TUINTPTR])
|
hn := temp(types.Types[types.TUINTPTR])
|
||||||
|
mul := conv(ir.Nod(ir.OMUL, ir.Nod(ir.OLEN, a, nil), nodintconst(elemsize)), types.Types[types.TUINTPTR])
|
||||||
tmp = ir.Nod(ir.OLEN, a, nil)
|
n.PtrBody().Append(ir.Nod(ir.OAS, hn, mul))
|
||||||
tmp = ir.Nod(ir.OMUL, tmp, nodintconst(elemsize))
|
|
||||||
tmp = conv(tmp, types.Types[types.TUINTPTR])
|
|
||||||
n.PtrBody().Append(ir.Nod(ir.OAS, hn, tmp))
|
|
||||||
|
|
||||||
var fn ir.Node
|
var fn ir.Node
|
||||||
if a.Type().Elem().HasPointers() {
|
if a.Type().Elem().HasPointers() {
|
||||||
|
|
@ -604,8 +597,7 @@ func arrayClear(loop, v1, v2, a ir.Node) ir.Node {
|
||||||
n.SetLeft(typecheck(n.Left(), ctxExpr))
|
n.SetLeft(typecheck(n.Left(), ctxExpr))
|
||||||
n.SetLeft(defaultlit(n.Left(), nil))
|
n.SetLeft(defaultlit(n.Left(), nil))
|
||||||
typecheckslice(n.Body().Slice(), ctxStmt)
|
typecheckslice(n.Body().Slice(), ctxStmt)
|
||||||
n = walkstmt(n)
|
return walkstmt(n)
|
||||||
return n
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// addptr returns (*T)(uintptr(p) + n).
|
// addptr returns (*T)(uintptr(p) + n).
|
||||||
|
|
|
||||||
|
|
@ -225,8 +225,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
|
||||||
if ir.IsBlank(elem) {
|
if ir.IsBlank(elem) {
|
||||||
elem = nodnil()
|
elem = nodnil()
|
||||||
}
|
}
|
||||||
receivedp := nodAddr(n.List().Second())
|
receivedp := typecheck(nodAddr(n.List().Second()), ctxExpr)
|
||||||
receivedp = typecheck(receivedp, ctxExpr)
|
|
||||||
call = mkcall1(chanfn("selectnbrecv2", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), elem, receivedp, ch)
|
call = mkcall1(chanfn("selectnbrecv2", 2, ch.Type()), types.Types[types.TBOOL], r.PtrInit(), elem, receivedp, ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -247,9 +246,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
|
||||||
// generate sel-struct
|
// generate sel-struct
|
||||||
base.Pos = sellineno
|
base.Pos = sellineno
|
||||||
selv := temp(types.NewArray(scasetype(), int64(ncas)))
|
selv := temp(types.NewArray(scasetype(), int64(ncas)))
|
||||||
r := ir.Nod(ir.OAS, selv, nil)
|
init = append(init, typecheck(ir.Nod(ir.OAS, selv, nil), ctxStmt))
|
||||||
r = typecheck(r, ctxStmt)
|
|
||||||
init = append(init, r)
|
|
||||||
|
|
||||||
// No initialization for order; runtime.selectgo is responsible for that.
|
// No initialization for order; runtime.selectgo is responsible for that.
|
||||||
order := temp(types.NewArray(types.Types[types.TUINT16], 2*int64(ncas)))
|
order := temp(types.NewArray(types.Types[types.TUINT16], 2*int64(ncas)))
|
||||||
|
|
@ -300,8 +297,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
|
||||||
|
|
||||||
setField := func(f string, val ir.Node) {
|
setField := func(f string, val ir.Node) {
|
||||||
r := ir.Nod(ir.OAS, nodSym(ir.ODOT, ir.Nod(ir.OINDEX, selv, nodintconst(int64(i))), lookup(f)), val)
|
r := ir.Nod(ir.OAS, nodSym(ir.ODOT, ir.Nod(ir.OINDEX, selv, nodintconst(int64(i))), lookup(f)), val)
|
||||||
r = typecheck(r, ctxStmt)
|
init = append(init, typecheck(r, ctxStmt))
|
||||||
init = append(init, r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c = convnop(c, types.Types[types.TUNSAFEPTR])
|
c = convnop(c, types.Types[types.TUNSAFEPTR])
|
||||||
|
|
@ -314,7 +310,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
|
||||||
// TODO(mdempsky): There should be a cleaner way to
|
// TODO(mdempsky): There should be a cleaner way to
|
||||||
// handle this.
|
// handle this.
|
||||||
if base.Flag.Race {
|
if base.Flag.Race {
|
||||||
r = mkcall("selectsetpc", nil, nil, nodAddr(ir.Nod(ir.OINDEX, pcs, nodintconst(int64(i)))))
|
r := mkcall("selectsetpc", nil, nil, nodAddr(ir.Nod(ir.OINDEX, pcs, nodintconst(int64(i)))))
|
||||||
init = append(init, r)
|
init = append(init, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -326,12 +322,11 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
|
||||||
base.Pos = sellineno
|
base.Pos = sellineno
|
||||||
chosen := temp(types.Types[types.TINT])
|
chosen := temp(types.Types[types.TINT])
|
||||||
recvOK := temp(types.Types[types.TBOOL])
|
recvOK := temp(types.Types[types.TBOOL])
|
||||||
r = ir.Nod(ir.OAS2, nil, nil)
|
r := ir.Nod(ir.OAS2, nil, nil)
|
||||||
r.PtrList().Set2(chosen, recvOK)
|
r.PtrList().Set2(chosen, recvOK)
|
||||||
fn := syslook("selectgo")
|
fn := syslook("selectgo")
|
||||||
r.PtrRlist().Set1(mkcall1(fn, fn.Type().Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(nsends)), nodintconst(int64(nrecvs)), nodbool(dflt == nil)))
|
r.PtrRlist().Set1(mkcall1(fn, fn.Type().Results(), nil, bytePtrToIndex(selv, 0), bytePtrToIndex(order, 0), pc0, nodintconst(int64(nsends)), nodintconst(int64(nrecvs)), nodbool(dflt == nil)))
|
||||||
r = typecheck(r, ctxStmt)
|
init = append(init, typecheck(r, ctxStmt))
|
||||||
init = append(init, r)
|
|
||||||
|
|
||||||
// selv and order are no longer alive after selectgo.
|
// selv and order are no longer alive after selectgo.
|
||||||
init = append(init, ir.Nod(ir.OVARKILL, selv, nil))
|
init = append(init, ir.Nod(ir.OVARKILL, selv, nil))
|
||||||
|
|
@ -349,8 +344,7 @@ func walkselectcases(cases *ir.Nodes) []ir.Node {
|
||||||
|
|
||||||
if n := cas.Left(); n != nil && n.Op() == ir.OSELRECV2 {
|
if n := cas.Left(); n != nil && n.Op() == ir.OSELRECV2 {
|
||||||
x := ir.Nod(ir.OAS, n.List().Second(), recvOK)
|
x := ir.Nod(ir.OAS, n.List().Second(), recvOK)
|
||||||
x = typecheck(x, ctxStmt)
|
r.PtrBody().Append(typecheck(x, ctxStmt))
|
||||||
r.PtrBody().Append(x)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r.PtrBody().AppendNodes(cas.PtrBody())
|
r.PtrBody().AppendNodes(cas.PtrBody())
|
||||||
|
|
|
||||||
|
|
@ -391,10 +391,7 @@ func isSimpleName(n ir.Node) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func litas(l ir.Node, r ir.Node, init *ir.Nodes) {
|
func litas(l ir.Node, r ir.Node, init *ir.Nodes) {
|
||||||
a := ir.Nod(ir.OAS, l, r)
|
appendWalkStmt(init, ir.Nod(ir.OAS, l, r))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
init.Append(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// initGenType is a bitmap indicating the types of generation that will occur for a static value.
|
// initGenType is a bitmap indicating the types of generation that will occur for a static value.
|
||||||
|
|
@ -528,7 +525,7 @@ func fixedlit(ctxt initContext, kind initKind, n ir.Node, var_ ir.Node, init *ir
|
||||||
a := ir.Nod(ir.OINDEX, var_, nodintconst(k))
|
a := ir.Nod(ir.OINDEX, var_, nodintconst(k))
|
||||||
k++
|
k++
|
||||||
if isBlank {
|
if isBlank {
|
||||||
a = ir.BlankNode
|
return ir.BlankNode, r
|
||||||
}
|
}
|
||||||
return a, r
|
return a, r
|
||||||
}
|
}
|
||||||
|
|
@ -691,20 +688,12 @@ func slicelit(ctxt initContext, n ir.Node, var_ ir.Node, init *ir.Nodes) {
|
||||||
} else {
|
} else {
|
||||||
a = ir.Nod(ir.ONEW, ir.TypeNode(t), nil)
|
a = ir.Nod(ir.ONEW, ir.TypeNode(t), nil)
|
||||||
}
|
}
|
||||||
|
appendWalkStmt(init, ir.Nod(ir.OAS, vauto, a))
|
||||||
a = ir.Nod(ir.OAS, vauto, a)
|
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
init.Append(a)
|
|
||||||
|
|
||||||
if vstat != nil {
|
if vstat != nil {
|
||||||
// copy static to heap (4)
|
// copy static to heap (4)
|
||||||
a = ir.Nod(ir.ODEREF, vauto, nil)
|
a = ir.Nod(ir.ODEREF, vauto, nil)
|
||||||
|
appendWalkStmt(init, ir.Nod(ir.OAS, a, vstat))
|
||||||
a = ir.Nod(ir.OAS, a, vstat)
|
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
init.Append(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// put dynamics into array (5)
|
// put dynamics into array (5)
|
||||||
|
|
@ -744,12 +733,10 @@ func slicelit(ctxt initContext, n ir.Node, var_ ir.Node, init *ir.Nodes) {
|
||||||
|
|
||||||
// build list of vauto[c] = expr
|
// build list of vauto[c] = expr
|
||||||
setlineno(value)
|
setlineno(value)
|
||||||
a = ir.Nod(ir.OAS, a, value)
|
as := typecheck(ir.Nod(ir.OAS, a, value), ctxStmt)
|
||||||
|
as = orderStmtInPlace(as, map[string][]*ir.Name{})
|
||||||
a = typecheck(a, ctxStmt)
|
as = walkstmt(as)
|
||||||
a = orderStmtInPlace(a, map[string][]*ir.Name{})
|
init.Append(as)
|
||||||
a = walkstmt(a)
|
|
||||||
init.Append(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// make slice out of heap (6)
|
// make slice out of heap (6)
|
||||||
|
|
@ -825,9 +812,7 @@ func maplit(n ir.Node, m ir.Node, init *ir.Nodes) {
|
||||||
loop.PtrBody().Set1(body)
|
loop.PtrBody().Set1(body)
|
||||||
loop.PtrInit().Set1(zero)
|
loop.PtrInit().Set1(zero)
|
||||||
|
|
||||||
loop = typecheck(loop, ctxStmt)
|
appendWalkStmt(init, loop)
|
||||||
loop = walkstmt(loop)
|
|
||||||
init.Append(loop)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// For a small number of entries, just add them directly.
|
// For a small number of entries, just add them directly.
|
||||||
|
|
@ -842,30 +827,17 @@ func maplit(n ir.Node, m ir.Node, init *ir.Nodes) {
|
||||||
index, elem := r.Left(), r.Right()
|
index, elem := r.Left(), r.Right()
|
||||||
|
|
||||||
setlineno(index)
|
setlineno(index)
|
||||||
a := ir.Nod(ir.OAS, tmpkey, index)
|
appendWalkStmt(init, ir.Nod(ir.OAS, tmpkey, index))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkstmt(a)
|
|
||||||
init.Append(a)
|
|
||||||
|
|
||||||
setlineno(elem)
|
setlineno(elem)
|
||||||
a = ir.Nod(ir.OAS, tmpelem, elem)
|
appendWalkStmt(init, ir.Nod(ir.OAS, tmpelem, elem))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkstmt(a)
|
|
||||||
init.Append(a)
|
|
||||||
|
|
||||||
setlineno(tmpelem)
|
setlineno(tmpelem)
|
||||||
a = ir.Nod(ir.OAS, ir.Nod(ir.OINDEX, m, tmpkey), tmpelem)
|
appendWalkStmt(init, ir.Nod(ir.OAS, ir.Nod(ir.OINDEX, m, tmpkey), tmpelem))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkstmt(a)
|
|
||||||
init.Append(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a = ir.Nod(ir.OVARKILL, tmpkey, nil)
|
appendWalkStmt(init, ir.Nod(ir.OVARKILL, tmpkey, nil))
|
||||||
a = typecheck(a, ctxStmt)
|
appendWalkStmt(init, ir.Nod(ir.OVARKILL, tmpelem, nil))
|
||||||
init.Append(a)
|
|
||||||
a = ir.Nod(ir.OVARKILL, tmpelem, nil)
|
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
init.Append(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
|
func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
|
||||||
|
|
@ -875,9 +847,7 @@ func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
|
||||||
base.Fatalf("anylit: not lit, op=%v node=%v", n.Op(), n)
|
base.Fatalf("anylit: not lit, op=%v node=%v", n.Op(), n)
|
||||||
|
|
||||||
case ir.ONAME, ir.OMETHEXPR:
|
case ir.ONAME, ir.OMETHEXPR:
|
||||||
a := ir.Nod(ir.OAS, var_, n)
|
appendWalkStmt(init, ir.Nod(ir.OAS, var_, n))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
init.Append(a)
|
|
||||||
|
|
||||||
case ir.OPTRLIT:
|
case ir.OPTRLIT:
|
||||||
if !t.IsPtr() {
|
if !t.IsPtr() {
|
||||||
|
|
@ -887,20 +857,13 @@ func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
|
||||||
var r ir.Node
|
var r ir.Node
|
||||||
if n.Right() != nil {
|
if n.Right() != nil {
|
||||||
// n.Right is stack temporary used as backing store.
|
// 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)
|
appendWalkStmt(init, ir.Nod(ir.OAS, n.Right(), nil)) // zero backing store, just in case (#18410)
|
||||||
r = nodAddr(n.Right())
|
r = nodAddr(n.Right())
|
||||||
r = typecheck(r, ctxExpr)
|
|
||||||
} else {
|
} else {
|
||||||
r = ir.Nod(ir.ONEW, ir.TypeNode(n.Left().Type()), nil)
|
r = ir.Nod(ir.ONEW, ir.TypeNode(n.Left().Type()), nil)
|
||||||
r = typecheck(r, ctxExpr)
|
|
||||||
r.SetEsc(n.Esc())
|
r.SetEsc(n.Esc())
|
||||||
}
|
}
|
||||||
|
appendWalkStmt(init, ir.Nod(ir.OAS, var_, r))
|
||||||
r = walkexpr(r, init)
|
|
||||||
a := ir.Nod(ir.OAS, var_, r)
|
|
||||||
|
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
init.Append(a)
|
|
||||||
|
|
||||||
var_ = ir.Nod(ir.ODEREF, var_, nil)
|
var_ = ir.Nod(ir.ODEREF, var_, nil)
|
||||||
var_ = typecheck(var_, ctxExpr|ctxAssign)
|
var_ = typecheck(var_, ctxExpr|ctxAssign)
|
||||||
|
|
@ -922,11 +885,7 @@ func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
|
||||||
fixedlit(ctxt, initKindStatic, n, vstat, init)
|
fixedlit(ctxt, initKindStatic, n, vstat, init)
|
||||||
|
|
||||||
// copy static to var
|
// copy static to var
|
||||||
a := ir.Nod(ir.OAS, var_, vstat)
|
appendWalkStmt(init, ir.Nod(ir.OAS, var_, vstat))
|
||||||
|
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
init.Append(a)
|
|
||||||
|
|
||||||
// add expressions to automatic
|
// add expressions to automatic
|
||||||
fixedlit(inInitFunction, initKindDynamic, n, var_, init)
|
fixedlit(inInitFunction, initKindDynamic, n, var_, init)
|
||||||
|
|
@ -941,10 +900,7 @@ func anylit(n ir.Node, var_ ir.Node, init *ir.Nodes) {
|
||||||
}
|
}
|
||||||
// initialization of an array or struct with unspecified components (missing fields or arrays)
|
// initialization of an array or struct with unspecified components (missing fields or arrays)
|
||||||
if isSimpleName(var_) || int64(n.List().Len()) < components {
|
if isSimpleName(var_) || int64(n.List().Len()) < components {
|
||||||
a := ir.Nod(ir.OAS, var_, nil)
|
appendWalkStmt(init, ir.Nod(ir.OAS, var_, nil))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
init.Append(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedlit(inInitFunction, initKindLocalCode, n, var_, init)
|
fixedlit(inInitFunction, initKindLocalCode, n, var_, init)
|
||||||
|
|
|
||||||
|
|
@ -153,12 +153,14 @@ func checkDotImports() {
|
||||||
dotImportRefs = nil
|
dotImportRefs = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// nodAddr returns a node representing &n.
|
// nodAddr returns a node representing &n at base.Pos.
|
||||||
func nodAddr(n ir.Node) ir.Node {
|
func nodAddr(n ir.Node) *ir.AddrExpr {
|
||||||
return ir.Nod(ir.OADDR, n, nil)
|
return nodAddrAt(base.Pos, n)
|
||||||
}
|
}
|
||||||
func nodAddrAt(pos src.XPos, n ir.Node) ir.Node {
|
|
||||||
return ir.NodAt(pos, ir.OADDR, n, nil)
|
// nodAddrPos returns a node representing &n at position pos.
|
||||||
|
func nodAddrAt(pos src.XPos, n ir.Node) *ir.AddrExpr {
|
||||||
|
return ir.NewAddrExpr(pos, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// newname returns a new ONAME Node associated with symbol s.
|
// newname returns a new ONAME Node associated with symbol s.
|
||||||
|
|
@ -774,10 +776,7 @@ func safeexpr(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
|
|
||||||
func copyexpr(n ir.Node, t *types.Type, init *ir.Nodes) ir.Node {
|
func copyexpr(n ir.Node, t *types.Type, init *ir.Nodes) ir.Node {
|
||||||
l := temp(t)
|
l := temp(t)
|
||||||
a := ir.Nod(ir.OAS, l, n)
|
appendWalkStmt(init, ir.Nod(ir.OAS, l, n))
|
||||||
a = typecheck(a, ctxStmt)
|
|
||||||
a = walkexpr(a, init)
|
|
||||||
init.Append(a)
|
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1195,11 +1194,12 @@ func genwrapper(rcvr *types.Type, method *types.Field, newnam *types.Sym) {
|
||||||
call.PtrList().Set(paramNnames(tfn.Type()))
|
call.PtrList().Set(paramNnames(tfn.Type()))
|
||||||
call.SetIsDDD(tfn.Type().IsVariadic())
|
call.SetIsDDD(tfn.Type().IsVariadic())
|
||||||
if method.Type.NumResults() > 0 {
|
if method.Type.NumResults() > 0 {
|
||||||
n := ir.Nod(ir.ORETURN, nil, nil)
|
ret := ir.Nod(ir.ORETURN, nil, nil)
|
||||||
n.PtrList().Set1(call)
|
ret.PtrList().Set1(call)
|
||||||
call = n
|
fn.PtrBody().Append(ret)
|
||||||
|
} else {
|
||||||
|
fn.PtrBody().Append(call)
|
||||||
}
|
}
|
||||||
fn.PtrBody().Append(call)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if false && base.Flag.LowerR != 0 {
|
if false && base.Flag.LowerR != 0 {
|
||||||
|
|
|
||||||
|
|
@ -654,9 +654,7 @@ func (s *typeSwitch) Add(pos src.XPos, typ *types.Type, caseVar, jmp ir.Node) {
|
||||||
dot := ir.NodAt(pos, ir.ODOTTYPE, s.facename, nil)
|
dot := ir.NodAt(pos, ir.ODOTTYPE, s.facename, nil)
|
||||||
dot.SetType(typ) // iface.(type)
|
dot.SetType(typ) // iface.(type)
|
||||||
as.PtrRlist().Set1(dot)
|
as.PtrRlist().Set1(dot)
|
||||||
as = typecheck(as, ctxStmt)
|
appendWalkStmt(&body, as)
|
||||||
as = walkexpr(as, &body)
|
|
||||||
body.Append(as)
|
|
||||||
|
|
||||||
// if ok { goto label }
|
// if ok { goto label }
|
||||||
nif := ir.NodAt(pos, ir.OIF, nil, nil)
|
nif := ir.NodAt(pos, ir.OIF, nil, nil)
|
||||||
|
|
|
||||||
|
|
@ -2163,8 +2163,7 @@ func typecheckargs(n ir.Node) {
|
||||||
Curfn = nil
|
Curfn = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
as = typecheck(as, ctxStmt)
|
n.PtrInit().Append(typecheck(as, ctxStmt))
|
||||||
n.PtrInit().Append(as)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool {
|
func checksliceindex(l ir.Node, r ir.Node, tp *types.Type) bool {
|
||||||
|
|
@ -2397,7 +2396,7 @@ func typecheckMethodExpr(n ir.Node) (res ir.Node) {
|
||||||
me.SetType(methodfunc(m.Type, n.Left().Type()))
|
me.SetType(methodfunc(m.Type, n.Left().Type()))
|
||||||
me.SetOffset(0)
|
me.SetOffset(0)
|
||||||
me.SetClass(ir.PFUNC)
|
me.SetClass(ir.PFUNC)
|
||||||
me.(*ir.MethodExpr).Method = m
|
ir.Node(me).(*ir.MethodExpr).Method = m
|
||||||
|
|
||||||
// Issue 25065. Make sure that we emit the symbol for a local method.
|
// Issue 25065. Make sure that we emit the symbol for a local method.
|
||||||
if base.Ctxt.Flag_dynlink && !inimport && (t.Sym() == nil || t.Sym().Pkg == types.LocalPkg) {
|
if base.Ctxt.Flag_dynlink && !inimport && (t.Sym() == nil || t.Sym().Pkg == types.LocalPkg) {
|
||||||
|
|
@ -3419,8 +3418,7 @@ func stringtoruneslit(n ir.Node) ir.Node {
|
||||||
|
|
||||||
nn := ir.Nod(ir.OCOMPLIT, nil, ir.TypeNode(n.Type()))
|
nn := ir.Nod(ir.OCOMPLIT, nil, ir.TypeNode(n.Type()))
|
||||||
nn.PtrList().Set(l)
|
nn.PtrList().Set(l)
|
||||||
nn = typecheck(nn, ctxExpr)
|
return typecheck(nn, ctxExpr)
|
||||||
return nn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var mapqueue []*ir.MapType
|
var mapqueue []*ir.MapType
|
||||||
|
|
|
||||||
|
|
@ -1306,8 +1306,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
|
bsym := hmapType.Field(5).Sym // hmap.buckets see reflect.go:hmap
|
||||||
na := ir.Nod(ir.OAS, nodSym(ir.ODOT, h, bsym), b)
|
na := ir.Nod(ir.OAS, nodSym(ir.ODOT, h, bsym), b)
|
||||||
nif.PtrBody().Append(na)
|
nif.PtrBody().Append(na)
|
||||||
|
appendWalkStmt(init, nif)
|
||||||
init.Append(walkstmt(typecheck(nif, ctxStmt)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1325,7 +1324,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
// h.hash0 = fastrand()
|
// h.hash0 = fastrand()
|
||||||
rand := mkcall("fastrand", types.Types[types.TUINT32], init)
|
rand := mkcall("fastrand", types.Types[types.TUINT32], init)
|
||||||
hashsym := hmapType.Field(4).Sym // hmap.hash0 see reflect.go:hmap
|
hashsym := hmapType.Field(4).Sym // hmap.hash0 see reflect.go:hmap
|
||||||
appendWalk(init, ir.Nod(ir.OAS, nodSym(ir.ODOT, h, hashsym), rand))
|
appendWalkStmt(init, ir.Nod(ir.OAS, nodSym(ir.ODOT, h, hashsym), rand))
|
||||||
return convnop(h, t)
|
return convnop(h, t)
|
||||||
}
|
}
|
||||||
// Call runtime.makehmap to allocate an
|
// Call runtime.makehmap to allocate an
|
||||||
|
|
@ -1398,8 +1397,8 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
|
|
||||||
t = types.NewArray(t.Elem(), i) // [r]T
|
t = types.NewArray(t.Elem(), i) // [r]T
|
||||||
var_ := temp(t)
|
var_ := temp(t)
|
||||||
appendWalk(init, ir.Nod(ir.OAS, var_, nil)) // zero temp
|
appendWalkStmt(init, ir.Nod(ir.OAS, var_, nil)) // zero temp
|
||||||
r := ir.Nod(ir.OSLICE, var_, nil) // arr[:l]
|
r := ir.Nod(ir.OSLICE, var_, nil) // arr[:l]
|
||||||
r.SetSliceBounds(nil, l, nil)
|
r.SetSliceBounds(nil, l, nil)
|
||||||
// The conv is necessary in case n.Type is named.
|
// The conv is necessary in case n.Type is named.
|
||||||
return walkexpr(typecheck(conv(r, n.Type()), ctxExpr), init)
|
return walkexpr(typecheck(conv(r, n.Type()), ctxExpr), init)
|
||||||
|
|
@ -1547,7 +1546,7 @@ func walkexpr1(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
as := ir.Nod(ir.OAS,
|
as := ir.Nod(ir.OAS,
|
||||||
ir.Nod(ir.ODEREF, p, nil),
|
ir.Nod(ir.ODEREF, p, nil),
|
||||||
ir.Nod(ir.ODEREF, convnop(ir.Nod(ir.OSPTR, s, nil), t.PtrTo()), nil))
|
ir.Nod(ir.ODEREF, convnop(ir.Nod(ir.OSPTR, s, nil), t.PtrTo()), nil))
|
||||||
appendWalk(init, as)
|
appendWalkStmt(init, as)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slice the [n]byte to a []byte.
|
// Slice the [n]byte to a []byte.
|
||||||
|
|
@ -2807,7 +2806,7 @@ func appendslice(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
|
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
|
||||||
ix := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
|
ix := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
|
||||||
ix.SetBounded(true)
|
ix.SetBounded(true)
|
||||||
addr := ir.Nod(ir.OADDR, ix, nil)
|
addr := nodAddr(ix)
|
||||||
|
|
||||||
sptr := ir.Nod(ir.OSPTR, l2, nil)
|
sptr := ir.Nod(ir.OSPTR, l2, nil)
|
||||||
|
|
||||||
|
|
@ -2953,7 +2952,7 @@ func extendslice(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
// hp := &s[len(l1)]
|
// hp := &s[len(l1)]
|
||||||
ix := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
|
ix := ir.Nod(ir.OINDEX, s, ir.Nod(ir.OLEN, l1, nil))
|
||||||
ix.SetBounded(true)
|
ix.SetBounded(true)
|
||||||
hp := convnop(ir.Nod(ir.OADDR, ix, nil), types.Types[types.TUNSAFEPTR])
|
hp := convnop(nodAddr(ix), types.Types[types.TUNSAFEPTR])
|
||||||
|
|
||||||
// hn := l2 * sizeof(elem(s))
|
// hn := l2 * sizeof(elem(s))
|
||||||
hn := conv(ir.Nod(ir.OMUL, l2, nodintconst(elemtype.Width)), types.Types[types.TUINTPTR])
|
hn := conv(ir.Nod(ir.OMUL, l2, nodintconst(elemtype.Width)), types.Types[types.TUINTPTR])
|
||||||
|
|
@ -4071,3 +4070,19 @@ func walkCheckPtrArithmetic(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
func checkPtr(fn *ir.Func, level int) bool {
|
func checkPtr(fn *ir.Func, level int) bool {
|
||||||
return base.Debug.Checkptr >= level && fn.Pragma&ir.NoCheckPtr == 0
|
return base.Debug.Checkptr >= level && fn.Pragma&ir.NoCheckPtr == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// appendWalkStmt typechecks and walks stmt and then appends it to init.
|
||||||
|
func appendWalkStmt(init *ir.Nodes, stmt ir.Node) {
|
||||||
|
op := stmt.Op()
|
||||||
|
n := typecheck(stmt, ctxStmt)
|
||||||
|
if op == ir.OAS || op == ir.OAS2 {
|
||||||
|
// If the assignment has side effects, walkexpr will append them
|
||||||
|
// directly to init for us, while walkstmt will wrap it in an OBLOCK.
|
||||||
|
// We need to append them directly.
|
||||||
|
// TODO(rsc): Clean this up.
|
||||||
|
n = walkexpr(n, init)
|
||||||
|
} else {
|
||||||
|
n = walkstmt(n)
|
||||||
|
}
|
||||||
|
init.Append(n)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue