mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
cmd/compile/internal/gc: unexport more helper functions
After the removal of the old backend many types are no longer referenced outside internal/gc. Make these functions private so that tools like honnef.co/go/unused can spot when they become dead code. In doing so this CL identified several previously public helpers which are no longer used, so removes them. This should be the last of the public functions. Change-Id: I7e9c4e72f86f391b428b9dddb6f0d516529706c3 Reviewed-on: https://go-review.googlesource.com/29134 Run-TryBot: Dave Cheney <dave@cheney.net> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
896ac677b5
commit
d7012ca282
@ -198,10 +198,10 @@ func genhash(sym *Sym, t *Type) {
|
|||||||
tfn := Nod(OTFUNC, nil, nil)
|
tfn := Nod(OTFUNC, nil, nil)
|
||||||
fn.Func.Nname.Name.Param.Ntype = tfn
|
fn.Func.Nname.Name.Param.Ntype = tfn
|
||||||
|
|
||||||
n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t)))
|
n := Nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)))
|
||||||
tfn.List.Append(n)
|
tfn.List.Append(n)
|
||||||
np := n.Left
|
np := n.Left
|
||||||
n = Nod(ODCLFIELD, newname(Lookup("h")), typenod(Types[TUINTPTR]))
|
n = Nod(ODCLFIELD, newname(lookup("h")), typenod(Types[TUINTPTR]))
|
||||||
tfn.List.Append(n)
|
tfn.List.Append(n)
|
||||||
nh := n.Left
|
nh := n.Left
|
||||||
n = Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])) // return value
|
n = Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])) // return value
|
||||||
@ -224,7 +224,7 @@ func genhash(sym *Sym, t *Type) {
|
|||||||
hashel := hashfor(t.Elem())
|
hashel := hashfor(t.Elem())
|
||||||
|
|
||||||
n := Nod(ORANGE, nil, Nod(OIND, np, nil))
|
n := Nod(ORANGE, nil, Nod(OIND, np, nil))
|
||||||
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.Colas = true
|
||||||
@ -260,7 +260,7 @@ func genhash(sym *Sym, t *Type) {
|
|||||||
if !f.Type.IsRegularMemory() {
|
if !f.Type.IsRegularMemory() {
|
||||||
hashel := hashfor(f.Type)
|
hashel := hashfor(f.Type)
|
||||||
call := Nod(OCALL, hashel, nil)
|
call := Nod(OCALL, hashel, nil)
|
||||||
nx := NodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
|
nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
|
||||||
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)
|
||||||
@ -276,7 +276,7 @@ func genhash(sym *Sym, t *Type) {
|
|||||||
// h = hashel(&p.first, size, h)
|
// h = hashel(&p.first, size, h)
|
||||||
hashel := hashmem(f.Type)
|
hashel := hashmem(f.Type)
|
||||||
call := Nod(OCALL, hashel, nil)
|
call := Nod(OCALL, hashel, nil)
|
||||||
nx := NodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
|
nx := nodSym(OXDOT, np, f.Sym) // TODO: fields from other packages?
|
||||||
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)
|
||||||
@ -347,7 +347,7 @@ func hashfor(t *Type) *Node {
|
|||||||
n := newname(sym)
|
n := newname(sym)
|
||||||
n.Class = PFUNC
|
n.Class = PFUNC
|
||||||
tfn := Nod(OTFUNC, nil, nil)
|
tfn := Nod(OTFUNC, nil, nil)
|
||||||
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
|
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(ptrto(t))))
|
||||||
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
||||||
tfn.Rlist.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
tfn.Rlist.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
||||||
tfn = typecheck(tfn, Etype)
|
tfn = typecheck(tfn, Etype)
|
||||||
@ -374,10 +374,10 @@ func geneq(sym *Sym, t *Type) {
|
|||||||
tfn := Nod(OTFUNC, nil, nil)
|
tfn := Nod(OTFUNC, nil, nil)
|
||||||
fn.Func.Nname.Name.Param.Ntype = tfn
|
fn.Func.Nname.Name.Param.Ntype = tfn
|
||||||
|
|
||||||
n := Nod(ODCLFIELD, newname(Lookup("p")), typenod(Ptrto(t)))
|
n := Nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)))
|
||||||
tfn.List.Append(n)
|
tfn.List.Append(n)
|
||||||
np := n.Left
|
np := n.Left
|
||||||
n = Nod(ODCLFIELD, newname(Lookup("q")), typenod(Ptrto(t)))
|
n = Nod(ODCLFIELD, newname(lookup("q")), typenod(ptrto(t)))
|
||||||
tfn.List.Append(n)
|
tfn.List.Append(n)
|
||||||
nq := n.Left
|
nq := n.Left
|
||||||
n = Nod(ODCLFIELD, nil, typenod(Types[TBOOL]))
|
n = Nod(ODCLFIELD, nil, typenod(Types[TBOOL]))
|
||||||
@ -401,7 +401,7 @@ func geneq(sym *Sym, t *Type) {
|
|||||||
// unrolling.
|
// unrolling.
|
||||||
nrange := Nod(ORANGE, nil, Nod(OIND, np, nil))
|
nrange := Nod(ORANGE, nil, Nod(OIND, np, nil))
|
||||||
|
|
||||||
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.Colas = true
|
||||||
@ -418,14 +418,14 @@ func geneq(sym *Sym, t *Type) {
|
|||||||
nif := Nod(OIF, nil, nil)
|
nif := Nod(OIF, nil, nil)
|
||||||
nif.Left = Nod(ONE, nx, ny)
|
nif.Left = Nod(ONE, nx, ny)
|
||||||
r := Nod(ORETURN, nil, nil)
|
r := Nod(ORETURN, nil, nil)
|
||||||
r.List.Append(Nodbool(false))
|
r.List.Append(nodbool(false))
|
||||||
nif.Nbody.Append(r)
|
nif.Nbody.Append(r)
|
||||||
nrange.Nbody.Append(nif)
|
nrange.Nbody.Append(nif)
|
||||||
fn.Nbody.Append(nrange)
|
fn.Nbody.Append(nrange)
|
||||||
|
|
||||||
// return true
|
// return true
|
||||||
ret := Nod(ORETURN, nil, nil)
|
ret := Nod(ORETURN, nil, nil)
|
||||||
ret.List.Append(Nodbool(true))
|
ret.List.Append(nodbool(true))
|
||||||
fn.Nbody.Append(ret)
|
fn.Nbody.Append(ret)
|
||||||
|
|
||||||
case TSTRUCT:
|
case TSTRUCT:
|
||||||
@ -474,7 +474,7 @@ func geneq(sym *Sym, t *Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cond == nil {
|
if cond == nil {
|
||||||
cond = Nodbool(true)
|
cond = nodbool(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret := Nod(ORETURN, nil, nil)
|
ret := Nod(ORETURN, nil, nil)
|
||||||
@ -518,8 +518,8 @@ func geneq(sym *Sym, t *Type) {
|
|||||||
// eqfield returns the node
|
// eqfield returns the node
|
||||||
// p.field == q.field
|
// p.field == q.field
|
||||||
func eqfield(p *Node, q *Node, field *Sym) *Node {
|
func eqfield(p *Node, q *Node, field *Sym) *Node {
|
||||||
nx := NodSym(OXDOT, p, field)
|
nx := nodSym(OXDOT, p, field)
|
||||||
ny := NodSym(OXDOT, q, field)
|
ny := nodSym(OXDOT, q, field)
|
||||||
ne := Nod(OEQ, nx, ny)
|
ne := Nod(OEQ, nx, ny)
|
||||||
return ne
|
return ne
|
||||||
}
|
}
|
||||||
@ -527,9 +527,9 @@ func eqfield(p *Node, q *Node, field *Sym) *Node {
|
|||||||
// eqmem returns the node
|
// eqmem returns the node
|
||||||
// memequal(&p.field, &q.field [, size])
|
// memequal(&p.field, &q.field [, size])
|
||||||
func eqmem(p *Node, q *Node, field *Sym, size int64) *Node {
|
func eqmem(p *Node, q *Node, field *Sym, size int64) *Node {
|
||||||
nx := Nod(OADDR, NodSym(OXDOT, p, field), nil)
|
nx := Nod(OADDR, nodSym(OXDOT, p, field), nil)
|
||||||
nx.Etype = 1 // does not escape
|
nx.Etype = 1 // does not escape
|
||||||
ny := Nod(OADDR, NodSym(OXDOT, q, field), nil)
|
ny := Nod(OADDR, nodSym(OXDOT, q, field), nil)
|
||||||
ny.Etype = 1 // does not escape
|
ny.Etype = 1 // does not escape
|
||||||
nx = typecheck(nx, Erv)
|
nx = typecheck(nx, Erv)
|
||||||
ny = typecheck(ny, Erv)
|
ny = typecheck(ny, Erv)
|
||||||
|
@ -21,7 +21,7 @@ func offmod(t *Type) {
|
|||||||
f.Offset = int64(o)
|
f.Offset = int64(o)
|
||||||
o += int32(Widthptr)
|
o += int32(Widthptr)
|
||||||
if int64(o) >= Thearch.MAXWIDTH {
|
if int64(o) >= Thearch.MAXWIDTH {
|
||||||
Yyerror("interface too large")
|
yyerror("interface too large")
|
||||||
o = int32(Widthptr)
|
o = int32(Widthptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +75,7 @@ func widstruct(errtype *Type, t *Type, o int64, flag int) int64 {
|
|||||||
}
|
}
|
||||||
o += w
|
o += w
|
||||||
if o >= Thearch.MAXWIDTH {
|
if o >= Thearch.MAXWIDTH {
|
||||||
Yyerror("type %L too large", errtype)
|
yyerror("type %L too large", errtype)
|
||||||
o = 8 // small but nonzero
|
o = 8 // small but nonzero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,7 +208,7 @@ func dowidth(t *Type) {
|
|||||||
t1 := t.ChanArgs()
|
t1 := t.ChanArgs()
|
||||||
dowidth(t1) // just in case
|
dowidth(t1) // just in case
|
||||||
if t1.Elem().Width >= 1<<16 {
|
if t1.Elem().Width >= 1<<16 {
|
||||||
Yyerror("channel element type too large (>64kB)")
|
yyerror("channel element type too large (>64kB)")
|
||||||
}
|
}
|
||||||
t.Width = 1
|
t.Width = 1
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ func dowidth(t *Type) {
|
|||||||
|
|
||||||
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
|
||||||
|
|
||||||
@ -243,7 +243,7 @@ func dowidth(t *Type) {
|
|||||||
}
|
}
|
||||||
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.Broke = true
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -253,7 +253,7 @@ func dowidth(t *Type) {
|
|||||||
if t.Elem().Width != 0 {
|
if t.Elem().Width != 0 {
|
||||||
cap := (uint64(Thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
|
cap := (uint64(Thearch.MAXWIDTH) - 1) / uint64(t.Elem().Width)
|
||||||
if uint64(t.NumElem()) > cap {
|
if uint64(t.NumElem()) > cap {
|
||||||
Yyerror("type %L larger than address space", t)
|
yyerror("type %L larger than address space", t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
w = t.NumElem() * t.Elem().Width
|
w = t.NumElem() * t.Elem().Width
|
||||||
@ -295,7 +295,7 @@ func dowidth(t *Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if Widthptr == 4 && w != int64(int32(w)) {
|
if Widthptr == 4 && w != int64(int32(w)) {
|
||||||
Yyerror("type %v too large", t)
|
yyerror("type %v too large", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Width = w
|
t.Width = w
|
||||||
|
@ -225,7 +225,7 @@ func formatErrorf(format string, args ...interface{}) {
|
|||||||
Fatalf(format, args...)
|
Fatalf(format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
Yyerror("cannot import %q due to version skew - reinstall package (%s)",
|
yyerror("cannot import %q due to version skew - reinstall package (%s)",
|
||||||
importpkg.Path, fmt.Sprintf(format, args...))
|
importpkg.Path, fmt.Sprintf(format, args...))
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
@ -287,10 +287,10 @@ func (p *importer) pkg() *Pkg {
|
|||||||
pkg.Name = name
|
pkg.Name = name
|
||||||
numImport[name]++
|
numImport[name]++
|
||||||
} else if pkg.Name != name {
|
} else if pkg.Name != name {
|
||||||
Yyerror("conflicting package names %s and %s for path %q", pkg.Name, name, path)
|
yyerror("conflicting package names %s and %s for path %q", pkg.Name, name, path)
|
||||||
}
|
}
|
||||||
if myimportpath != "" && path == myimportpath {
|
if myimportpath != "" && path == myimportpath {
|
||||||
Yyerror("import %q: package depends on %q (import cycle)", importpkg.Path, path)
|
yyerror("import %q: package depends on %q (import cycle)", importpkg.Path, path)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
p.pkgList = append(p.pkgList, pkg)
|
p.pkgList = append(p.pkgList, pkg)
|
||||||
@ -405,7 +405,7 @@ func (p *importer) importtype(pt, t *Type) {
|
|||||||
// Collect the types and verify identity later.
|
// Collect the types and verify identity later.
|
||||||
p.cmpList = append(p.cmpList, struct{ pt, t *Type }{pt, t})
|
p.cmpList = append(p.cmpList, struct{ pt, t *Type }{pt, t})
|
||||||
} else if !eqtype(pt.Orig, t) {
|
} else if !eqtype(pt.Orig, t) {
|
||||||
Yyerror("inconsistent definition for type %v during import\n\t%L (in %q)\n\t%L (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, importpkg.Path)
|
yyerror("inconsistent definition for type %v during import\n\t%L (in %q)\n\t%L (in %q)", pt.Sym, pt, pt.Sym.Importdef.Path, t, importpkg.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,7 +905,7 @@ func (p *importer) node() *Node {
|
|||||||
|
|
||||||
case OXDOT:
|
case OXDOT:
|
||||||
// see parser.new_dotname
|
// see parser.new_dotname
|
||||||
return NodSym(OXDOT, p.expr(), p.fieldSym())
|
return nodSym(OXDOT, p.expr(), p.fieldSym())
|
||||||
|
|
||||||
// case ODOTTYPE, ODOTTYPE2:
|
// case ODOTTYPE, ODOTTYPE2:
|
||||||
// unreachable - mapped to case ODOTTYPE below by exporter
|
// unreachable - mapped to case ODOTTYPE below by exporter
|
||||||
|
@ -195,7 +195,7 @@ func closurename(n *Node) *Sym {
|
|||||||
default:
|
default:
|
||||||
Fatalf("closurename called for %S", n)
|
Fatalf("closurename called for %S", n)
|
||||||
}
|
}
|
||||||
n.Sym = Lookupf("%s.%s%d", outer, prefix, gen)
|
n.Sym = lookupf("%s.%s%d", outer, prefix, gen)
|
||||||
return n.Sym
|
return n.Sym
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,8 +342,8 @@ func transformclosure(xfunc *Node) {
|
|||||||
// we introduce function param &v *T
|
// we introduce function param &v *T
|
||||||
// and v remains PAUTOHEAP with &v heapaddr
|
// and v remains PAUTOHEAP with &v heapaddr
|
||||||
// (accesses will implicitly deref &v).
|
// (accesses will implicitly deref &v).
|
||||||
addr := newname(Lookupf("&%s", v.Sym.Name))
|
addr := newname(lookupf("&%s", v.Sym.Name))
|
||||||
addr.Type = Ptrto(v.Type)
|
addr.Type = ptrto(v.Type)
|
||||||
addr.Class = PPARAM
|
addr.Class = PPARAM
|
||||||
v.Name.Heapaddr = addr
|
v.Name.Heapaddr = addr
|
||||||
fld.Nname = addr
|
fld.Nname = addr
|
||||||
@ -382,7 +382,7 @@ func transformclosure(xfunc *Node) {
|
|||||||
|
|
||||||
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
|
||||||
@ -397,7 +397,7 @@ func transformclosure(xfunc *Node) {
|
|||||||
} else {
|
} else {
|
||||||
// Declare variable holding addresses taken from closure
|
// Declare variable holding addresses taken from closure
|
||||||
// and initialize in entry prologue.
|
// and initialize in entry prologue.
|
||||||
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.Used = true
|
||||||
@ -476,7 +476,7 @@ func walkclosure(func_ *Node, init *Nodes) *Node {
|
|||||||
|
|
||||||
typ := Nod(OTSTRUCT, nil, nil)
|
typ := Nod(OTSTRUCT, nil, nil)
|
||||||
|
|
||||||
typ.List.Set1(Nod(ODCLFIELD, newname(Lookup(".F")), typenod(Types[TUINTPTR])))
|
typ.List.Set1(Nod(ODCLFIELD, newname(lookup(".F")), typenod(Types[TUINTPTR])))
|
||||||
for _, v := range func_.Func.Cvars.Slice() {
|
for _, v := range func_.Func.Cvars.Slice() {
|
||||||
if v.Op == OXXX {
|
if v.Op == OXXX {
|
||||||
continue
|
continue
|
||||||
@ -580,7 +580,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
|
|||||||
xfunc := Nod(ODCLFUNC, nil, nil)
|
xfunc := Nod(ODCLFUNC, nil, nil)
|
||||||
Curfn = xfunc
|
Curfn = xfunc
|
||||||
for i, t := range t0.Params().Fields().Slice() {
|
for i, t := range t0.Params().Fields().Slice() {
|
||||||
n := newname(LookupN("a", i))
|
n := newname(lookupN("a", i))
|
||||||
n.Class = PPARAM
|
n.Class = PPARAM
|
||||||
xfunc.Func.Dcl = append(xfunc.Func.Dcl, n)
|
xfunc.Func.Dcl = append(xfunc.Func.Dcl, n)
|
||||||
callargs = append(callargs, n)
|
callargs = append(callargs, n)
|
||||||
@ -597,7 +597,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
|
|||||||
l = nil
|
l = nil
|
||||||
var retargs []*Node
|
var retargs []*Node
|
||||||
for i, t := range t0.Results().Fields().Slice() {
|
for i, t := range t0.Results().Fields().Slice() {
|
||||||
n := newname(LookupN("r", i))
|
n := newname(lookupN("r", i))
|
||||||
n.Class = PPARAMOUT
|
n.Class = PPARAMOUT
|
||||||
xfunc.Func.Dcl = append(xfunc.Func.Dcl, n)
|
xfunc.Func.Dcl = append(xfunc.Func.Dcl, n)
|
||||||
retargs = append(retargs, n)
|
retargs = append(retargs, n)
|
||||||
@ -623,7 +623,7 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
|
|||||||
cv.Xoffset = int64(cv.Type.Align)
|
cv.Xoffset = int64(cv.Type.Align)
|
||||||
}
|
}
|
||||||
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.Addable = true
|
||||||
ptr.Ullman = 1
|
ptr.Ullman = 1
|
||||||
@ -636,11 +636,11 @@ func makepartialcall(fn *Node, t0 *Type, meth *Sym) *Node {
|
|||||||
ptr.Name.Param.Ntype = typenod(rcvrtype)
|
ptr.Name.Param.Ntype = typenod(rcvrtype)
|
||||||
body = append(body, Nod(OAS, ptr, cv))
|
body = append(body, Nod(OAS, ptr, cv))
|
||||||
} else {
|
} else {
|
||||||
ptr.Name.Param.Ntype = typenod(Ptrto(rcvrtype))
|
ptr.Name.Param.Ntype = typenod(ptrto(rcvrtype))
|
||||||
body = append(body, Nod(OAS, ptr, Nod(OADDR, cv, nil)))
|
body = append(body, Nod(OAS, ptr, Nod(OADDR, cv, nil)))
|
||||||
}
|
}
|
||||||
|
|
||||||
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.Isddd = ddd
|
||||||
if t0.Results().NumFields() == 0 {
|
if t0.Results().NumFields() == 0 {
|
||||||
@ -681,8 +681,8 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typ := Nod(OTSTRUCT, nil, nil)
|
typ := Nod(OTSTRUCT, nil, nil)
|
||||||
typ.List.Set1(Nod(ODCLFIELD, newname(Lookup("F")), typenod(Types[TUINTPTR])))
|
typ.List.Set1(Nod(ODCLFIELD, newname(lookup("F")), typenod(Types[TUINTPTR])))
|
||||||
typ.List.Append(Nod(ODCLFIELD, newname(Lookup("R")), typenod(n.Left.Type)))
|
typ.List.Append(Nod(ODCLFIELD, newname(lookup("R")), typenod(n.Left.Type)))
|
||||||
|
|
||||||
clos := Nod(OCOMPLIT, nil, Nod(OIND, typ, nil))
|
clos := Nod(OCOMPLIT, nil, Nod(OIND, typ, nil))
|
||||||
clos.Esc = n.Esc
|
clos.Esc = n.Esc
|
||||||
|
@ -190,13 +190,6 @@ func truncfltlit(oldv *Mpflt, t *Type) *Mpflt {
|
|||||||
return fv
|
return fv
|
||||||
}
|
}
|
||||||
|
|
||||||
// NegOne returns a Node of type t with value -1.
|
|
||||||
func NegOne(t *Type) *Node {
|
|
||||||
n := nodintconst(-1)
|
|
||||||
n = convlit(n, t)
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// canReuseNode indicates whether it is known to be safe
|
// canReuseNode indicates whether it is known to be safe
|
||||||
// to reuse a Node.
|
// to reuse a Node.
|
||||||
type canReuseNode bool
|
type canReuseNode bool
|
||||||
@ -265,7 +258,7 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node {
|
|||||||
n.SetVal(toint(n.Val()))
|
n.SetVal(toint(n.Val()))
|
||||||
}
|
}
|
||||||
if t != nil && !t.IsInteger() {
|
if t != nil && !t.IsInteger() {
|
||||||
Yyerror("invalid operation: %v (shift of type %v)", n, t)
|
yyerror("invalid operation: %v (shift of type %v)", n, t)
|
||||||
t = nil
|
t = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,7 +405,7 @@ func convlit1(n *Node, t *Type, explicit bool, reuse canReuseNode) *Node {
|
|||||||
bad:
|
bad:
|
||||||
if n.Diag == 0 {
|
if n.Diag == 0 {
|
||||||
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 = 1
|
n.Diag = 1
|
||||||
}
|
}
|
||||||
@ -475,7 +468,7 @@ func toflt(v Val) Val {
|
|||||||
f := newMpflt()
|
f := newMpflt()
|
||||||
f.Set(&u.Real)
|
f.Set(&u.Real)
|
||||||
if u.Imag.CmpFloat64(0) != 0 {
|
if u.Imag.CmpFloat64(0) != 0 {
|
||||||
Yyerror("constant %v%vi truncated to real", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign))
|
yyerror("constant %v%vi truncated to real", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign))
|
||||||
}
|
}
|
||||||
v.U = f
|
v.U = f
|
||||||
}
|
}
|
||||||
@ -500,17 +493,17 @@ func toint(v Val) Val {
|
|||||||
if u.Val.IsInt() {
|
if u.Val.IsInt() {
|
||||||
msg = "constant %v overflows integer"
|
msg = "constant %v overflows integer"
|
||||||
}
|
}
|
||||||
Yyerror(msg, fconv(u, FmtSharp))
|
yyerror(msg, fconv(u, FmtSharp))
|
||||||
}
|
}
|
||||||
v.U = i
|
v.U = i
|
||||||
|
|
||||||
case *Mpcplx:
|
case *Mpcplx:
|
||||||
i := new(Mpint)
|
i := new(Mpint)
|
||||||
if i.SetFloat(&u.Real) < 0 {
|
if i.SetFloat(&u.Real) < 0 {
|
||||||
Yyerror("constant %v%vi truncated to integer", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign))
|
yyerror("constant %v%vi truncated to integer", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign))
|
||||||
}
|
}
|
||||||
if u.Imag.CmpFloat64(0) != 0 {
|
if u.Imag.CmpFloat64(0) != 0 {
|
||||||
Yyerror("constant %v%vi truncated to real", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign))
|
yyerror("constant %v%vi truncated to real", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp|FmtSign))
|
||||||
}
|
}
|
||||||
v.U = i
|
v.U = i
|
||||||
}
|
}
|
||||||
@ -556,7 +549,7 @@ func overflow(v Val, t *Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if doesoverflow(v, t) {
|
if doesoverflow(v, t) {
|
||||||
Yyerror("constant %v overflows %v", v, t)
|
yyerror("constant %v overflows %v", v, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,7 +737,7 @@ 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 == 0 {
|
if n.Diag == 0 {
|
||||||
Yyerror("illegal constant expression %v %v", n.Op, nl.Type)
|
yyerror("illegal constant expression %v %v", n.Op, nl.Type)
|
||||||
n.Diag = 1
|
n.Diag = 1
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@ -939,7 +932,7 @@ func evconst(n *Node) {
|
|||||||
case ODIV_ | CTINT_,
|
case ODIV_ | CTINT_,
|
||||||
ODIV_ | CTRUNE_:
|
ODIV_ | CTRUNE_:
|
||||||
if rv.U.(*Mpint).CmpInt64(0) == 0 {
|
if rv.U.(*Mpint).CmpInt64(0) == 0 {
|
||||||
Yyerror("division by zero")
|
yyerror("division by zero")
|
||||||
v.U.(*Mpint).SetOverflow()
|
v.U.(*Mpint).SetOverflow()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -949,7 +942,7 @@ func evconst(n *Node) {
|
|||||||
case OMOD_ | CTINT_,
|
case OMOD_ | CTINT_,
|
||||||
OMOD_ | CTRUNE_:
|
OMOD_ | CTRUNE_:
|
||||||
if rv.U.(*Mpint).CmpInt64(0) == 0 {
|
if rv.U.(*Mpint).CmpInt64(0) == 0 {
|
||||||
Yyerror("division by zero")
|
yyerror("division by zero")
|
||||||
v.U.(*Mpint).SetOverflow()
|
v.U.(*Mpint).SetOverflow()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -991,7 +984,7 @@ func evconst(n *Node) {
|
|||||||
|
|
||||||
case ODIV_ | CTFLT_:
|
case ODIV_ | CTFLT_:
|
||||||
if rv.U.(*Mpflt).CmpFloat64(0) == 0 {
|
if rv.U.(*Mpflt).CmpFloat64(0) == 0 {
|
||||||
Yyerror("division by zero")
|
yyerror("division by zero")
|
||||||
v.U.(*Mpflt).SetFloat64(1.0)
|
v.U.(*Mpflt).SetFloat64(1.0)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -1002,7 +995,7 @@ func evconst(n *Node) {
|
|||||||
// which is not quite an ideal error.
|
// which is not quite an ideal error.
|
||||||
case OMOD_ | CTFLT_:
|
case OMOD_ | CTFLT_:
|
||||||
if n.Diag == 0 {
|
if n.Diag == 0 {
|
||||||
Yyerror("illegal constant expression: floating-point %% operation")
|
yyerror("illegal constant expression: floating-point %% operation")
|
||||||
n.Diag = 1
|
n.Diag = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,7 +1014,7 @@ func evconst(n *Node) {
|
|||||||
|
|
||||||
case ODIV_ | CTCPLX_:
|
case ODIV_ | CTCPLX_:
|
||||||
if rv.U.(*Mpcplx).Real.CmpFloat64(0) == 0 && rv.U.(*Mpcplx).Imag.CmpFloat64(0) == 0 {
|
if rv.U.(*Mpcplx).Real.CmpFloat64(0) == 0 && rv.U.(*Mpcplx).Imag.CmpFloat64(0) == 0 {
|
||||||
Yyerror("complex division by zero")
|
yyerror("complex division by zero")
|
||||||
rv.U.(*Mpcplx).Real.SetFloat64(1.0)
|
rv.U.(*Mpcplx).Real.SetFloat64(1.0)
|
||||||
rv.U.(*Mpcplx).Imag.SetFloat64(0.0)
|
rv.U.(*Mpcplx).Imag.SetFloat64(0.0)
|
||||||
break
|
break
|
||||||
@ -1209,7 +1202,7 @@ ret:
|
|||||||
return
|
return
|
||||||
|
|
||||||
settrue:
|
settrue:
|
||||||
nn = Nodbool(true)
|
nn = nodbool(true)
|
||||||
nn.Orig = saveorig(n)
|
nn.Orig = saveorig(n)
|
||||||
if !iscmp[n.Op] {
|
if !iscmp[n.Op] {
|
||||||
nn.Type = nl.Type
|
nn.Type = nl.Type
|
||||||
@ -1218,7 +1211,7 @@ settrue:
|
|||||||
return
|
return
|
||||||
|
|
||||||
setfalse:
|
setfalse:
|
||||||
nn = Nodbool(false)
|
nn = nodbool(false)
|
||||||
nn.Orig = saveorig(n)
|
nn.Orig = saveorig(n)
|
||||||
if !iscmp[n.Op] {
|
if !iscmp[n.Op] {
|
||||||
nn.Type = nl.Type
|
nn.Type = nl.Type
|
||||||
@ -1228,7 +1221,7 @@ setfalse:
|
|||||||
|
|
||||||
illegal:
|
illegal:
|
||||||
if n.Diag == 0 {
|
if n.Diag == 0 {
|
||||||
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 = 1
|
n.Diag = 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1369,7 +1362,7 @@ 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 == 0 {
|
if n.Diag == 0 {
|
||||||
Yyerror("use of untyped nil")
|
yyerror("use of untyped nil")
|
||||||
n.Diag = 1
|
n.Diag = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1383,7 +1376,7 @@ func defaultlitreuse(n *Node, t *Type, reuse canReuseNode) *Node {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
Yyerror("defaultlit: unknown literal: %v", n)
|
yyerror("defaultlit: unknown literal: %v", n)
|
||||||
|
|
||||||
case CTxxx:
|
case CTxxx:
|
||||||
Fatalf("defaultlit: idealkind is CTxxx: %+v", n)
|
Fatalf("defaultlit: idealkind is CTxxx: %+v", n)
|
||||||
|
@ -106,7 +106,7 @@ func testdclstack() {
|
|||||||
if nerrors != 0 {
|
if nerrors != 0 {
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
Yyerror("mark left on the stack")
|
yyerror("mark left on the stack")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ func redeclare(s *Sym, where string) {
|
|||||||
tmp = s.Pkg.Path
|
tmp = s.Pkg.Path
|
||||||
}
|
}
|
||||||
pkgstr := tmp
|
pkgstr := tmp
|
||||||
Yyerror("%v redeclared %s\n"+
|
yyerror("%v redeclared %s\n"+
|
||||||
"\tprevious declaration during import %q", s, where, pkgstr)
|
"\tprevious declaration during import %q", s, where, pkgstr)
|
||||||
} else {
|
} else {
|
||||||
line1 := lineno
|
line1 := lineno
|
||||||
@ -167,11 +167,11 @@ func declare(n *Node, ctxt Class) {
|
|||||||
|
|
||||||
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
|
// kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
|
||||||
if importpkg == nil && !typecheckok && s.Pkg != localpkg {
|
if importpkg == nil && !typecheckok && s.Pkg != localpkg {
|
||||||
Yyerror("cannot declare name %v", s)
|
yyerror("cannot declare name %v", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctxt == PEXTERN && s.Name == "init" {
|
if ctxt == PEXTERN && s.Name == "init" {
|
||||||
Yyerror("cannot declare init - must be func")
|
yyerror("cannot declare init - must be func")
|
||||||
}
|
}
|
||||||
|
|
||||||
gen := 0
|
gen := 0
|
||||||
@ -255,7 +255,7 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
|
|||||||
var e *Node
|
var e *Node
|
||||||
if doexpr {
|
if doexpr {
|
||||||
if len(el) == 0 {
|
if len(el) == 0 {
|
||||||
Yyerror("missing expression in var declaration")
|
yyerror("missing expression in var declaration")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
e = el[0]
|
e = el[0]
|
||||||
@ -279,7 +279,7 @@ func variter(vl []*Node, t *Node, el []*Node) []*Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(el) != 0 {
|
if len(el) != 0 {
|
||||||
Yyerror("extra expression in var declaration")
|
yyerror("extra expression in var declaration")
|
||||||
}
|
}
|
||||||
return init
|
return init
|
||||||
}
|
}
|
||||||
@ -290,7 +290,7 @@ func constiter(vl []*Node, t *Node, cl []*Node) []*Node {
|
|||||||
lno := int32(0) // default is to leave line number alone in listtreecopy
|
lno := int32(0) // default is to leave line number alone in listtreecopy
|
||||||
if len(cl) == 0 {
|
if len(cl) == 0 {
|
||||||
if t != nil {
|
if t != nil {
|
||||||
Yyerror("const declaration cannot have type without expression")
|
yyerror("const declaration cannot have type without expression")
|
||||||
}
|
}
|
||||||
cl = lastconst
|
cl = lastconst
|
||||||
t = lasttype
|
t = lasttype
|
||||||
@ -304,7 +304,7 @@ func constiter(vl []*Node, t *Node, cl []*Node) []*Node {
|
|||||||
var vv []*Node
|
var vv []*Node
|
||||||
for _, v := range vl {
|
for _, v := range vl {
|
||||||
if len(clcopy) == 0 {
|
if len(clcopy) == 0 {
|
||||||
Yyerror("missing value in const declaration")
|
yyerror("missing value in const declaration")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ func constiter(vl []*Node, t *Node, cl []*Node) []*Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(clcopy) != 0 {
|
if len(clcopy) != 0 {
|
||||||
Yyerror("extra expression in const declaration")
|
yyerror("extra expression in const declaration")
|
||||||
}
|
}
|
||||||
iota_ += 1
|
iota_ += 1
|
||||||
return vv
|
return vv
|
||||||
@ -504,7 +504,7 @@ func ifacedcl(n *Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isblank(n.Left) {
|
if isblank(n.Left) {
|
||||||
Yyerror("methods must have a unique non-blank name")
|
yyerror("methods must have a unique non-blank name")
|
||||||
}
|
}
|
||||||
|
|
||||||
n.Func = new(Func)
|
n.Func = new(Func)
|
||||||
@ -603,7 +603,7 @@ func funcargs(nt *Node) {
|
|||||||
|
|
||||||
if n.Left == nil {
|
if n.Left == nil {
|
||||||
// Name so that escape analysis can track it. ~r stands for 'result'.
|
// Name so that escape analysis can track it. ~r stands for 'result'.
|
||||||
n.Left = newname(LookupN("~r", gen))
|
n.Left = newname(lookupN("~r", gen))
|
||||||
gen++
|
gen++
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -621,7 +621,7 @@ func funcargs(nt *Node) {
|
|||||||
// Having multiple names causes too much confusion in later passes.
|
// Having multiple names causes too much confusion in later passes.
|
||||||
nn := *n.Left
|
nn := *n.Left
|
||||||
nn.Orig = &nn
|
nn.Orig = &nn
|
||||||
nn.Sym = LookupN("~b", gen)
|
nn.Sym = lookupN("~b", gen)
|
||||||
gen++
|
gen++
|
||||||
n.Left = &nn
|
n.Left = &nn
|
||||||
}
|
}
|
||||||
@ -726,12 +726,12 @@ func checkembeddedtype(t *Type) {
|
|||||||
if t.Sym == nil && t.IsPtr() {
|
if t.Sym == nil && t.IsPtr() {
|
||||||
t = t.Elem()
|
t = t.Elem()
|
||||||
if t.IsInterface() {
|
if t.IsInterface() {
|
||||||
Yyerror("embedded type cannot be a pointer to interface")
|
yyerror("embedded type cannot be a pointer to interface")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.IsPtr() || t.IsUnsafePtr() {
|
if t.IsPtr() || t.IsUnsafePtr() {
|
||||||
Yyerror("embedded type cannot be a pointer")
|
yyerror("embedded type cannot be a pointer")
|
||||||
} else if t.Etype == TFORW && t.ForwardType().Embedlineno == 0 {
|
} else if t.Etype == TFORW && t.ForwardType().Embedlineno == 0 {
|
||||||
t.ForwardType().Embedlineno = lineno
|
t.ForwardType().Embedlineno = lineno
|
||||||
}
|
}
|
||||||
@ -770,7 +770,7 @@ func structfield(n *Node) *Field {
|
|||||||
case string:
|
case string:
|
||||||
f.Note = u
|
f.Note = u
|
||||||
default:
|
default:
|
||||||
Yyerror("field annotation must be string")
|
yyerror("field annotation must be string")
|
||||||
case nil:
|
case nil:
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
@ -798,7 +798,7 @@ func checkdupfields(what string, ts ...*Type) {
|
|||||||
}
|
}
|
||||||
if seen[f.Sym] {
|
if seen[f.Sym] {
|
||||||
lineno = f.Nname.Lineno
|
lineno = f.Nname.Lineno
|
||||||
Yyerror("duplicate %s %s", what, f.Sym.Name)
|
yyerror("duplicate %s %s", what, f.Sym.Name)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
seen[f.Sym] = true
|
seen[f.Sym] = true
|
||||||
@ -869,7 +869,7 @@ func interfacefield(n *Node) *Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n.Val().Ctype() != CTxxx {
|
if n.Val().Ctype() != CTxxx {
|
||||||
Yyerror("interface method cannot have annotation")
|
yyerror("interface method cannot have annotation")
|
||||||
}
|
}
|
||||||
|
|
||||||
f := newField()
|
f := newField()
|
||||||
@ -904,11 +904,11 @@ func interfacefield(n *Node) *Field {
|
|||||||
break
|
break
|
||||||
|
|
||||||
case TFORW:
|
case TFORW:
|
||||||
Yyerror("interface type loop involving %v", n.Type)
|
yyerror("interface type loop involving %v", n.Type)
|
||||||
f.Broke = true
|
f.Broke = 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.Broke = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -984,7 +984,7 @@ func embedded(s *Sym, pkg *Pkg) *Node {
|
|||||||
|
|
||||||
var n *Node
|
var n *Node
|
||||||
if exportname(name) {
|
if exportname(name) {
|
||||||
n = newname(Lookup(name))
|
n = newname(lookup(name))
|
||||||
} else if s.Pkg == builtinpkg {
|
} else if s.Pkg == builtinpkg {
|
||||||
// The name of embedded builtins belongs to pkg.
|
// The name of embedded builtins belongs to pkg.
|
||||||
n = newname(Pkglookup(name, pkg))
|
n = newname(Pkglookup(name, pkg))
|
||||||
@ -997,7 +997,7 @@ func embedded(s *Sym, pkg *Pkg) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func fakethis() *Node {
|
func fakethis() *Node {
|
||||||
n := Nod(ODCLFIELD, nil, typenod(Ptrto(typ(TSTRUCT))))
|
n := Nod(ODCLFIELD, nil, typenod(ptrto(typ(TSTRUCT))))
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,7 +1084,7 @@ func methodsym(nsym *Sym, t0 *Type, iface int) *Sym {
|
|||||||
// if t0 == *t and t0 has a sym,
|
// if t0 == *t and t0 has a sym,
|
||||||
// we want to see *t, not t0, in the method name.
|
// we want to see *t, not t0, in the method name.
|
||||||
if t != t0 && t0.Sym != nil {
|
if t != t0 && t0.Sym != nil {
|
||||||
t0 = Ptrto(t)
|
t0 = ptrto(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
suffix = ""
|
suffix = ""
|
||||||
@ -1121,7 +1121,7 @@ func methodsym(nsym *Sym, t0 *Type, iface int) *Sym {
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
Yyerror("illegal receiver type: %v", t0)
|
yyerror("illegal receiver type: %v", t0)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1144,7 +1144,7 @@ func methodname(n *Node, t *Node) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if exportname(t.Sym.Name) {
|
if exportname(t.Sym.Name) {
|
||||||
n = newfuncname(Lookup(p))
|
n = newfuncname(lookup(p))
|
||||||
} else {
|
} else {
|
||||||
n = newfuncname(Pkglookup(p, t.Sym.Pkg))
|
n = newfuncname(Pkglookup(p, t.Sym.Pkg))
|
||||||
}
|
}
|
||||||
@ -1164,7 +1164,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
|
|||||||
// get parent type sym
|
// get parent type sym
|
||||||
rf := t.Recv() // ptr to this structure
|
rf := t.Recv() // ptr to this structure
|
||||||
if rf == nil {
|
if rf == nil {
|
||||||
Yyerror("missing receiver")
|
yyerror("missing receiver")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1174,7 +1174,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
|
|||||||
t := pa
|
t := pa
|
||||||
if t != nil && t.IsPtr() {
|
if t != nil && t.IsPtr() {
|
||||||
if t.Sym != nil {
|
if t.Sym != nil {
|
||||||
Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
|
yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
t = t.Elem()
|
t = t.Elem()
|
||||||
@ -1184,21 +1184,21 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
|
|||||||
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)
|
||||||
case t.IsPtr():
|
case t.IsPtr():
|
||||||
Yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
|
yyerror("invalid receiver type %v (%v is a pointer type)", pa, t)
|
||||||
case t.IsInterface():
|
case t.IsInterface():
|
||||||
Yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
|
yyerror("invalid receiver type %v (%v is an interface type)", pa, t)
|
||||||
default:
|
default:
|
||||||
// Should have picked off all the reasons above,
|
// Should have picked off all the reasons above,
|
||||||
// but just in case, fall back to generic error.
|
// but just in case, fall back to generic error.
|
||||||
Yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
|
yyerror("invalid receiver type %v (%L / %L)", pa, pa, t)
|
||||||
}
|
}
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1209,7 +1209,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
|
|||||||
if mt.IsStruct() {
|
if mt.IsStruct() {
|
||||||
for _, f := range mt.Fields().Slice() {
|
for _, f := range mt.Fields().Slice() {
|
||||||
if f.Sym == msym {
|
if f.Sym == msym {
|
||||||
Yyerror("type %v has both field and method named %v", mt, msym)
|
yyerror("type %v has both field and method named %v", mt, msym)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1225,7 +1225,7 @@ func addmethod(msym *Sym, t *Type, local, nointerface bool) {
|
|||||||
// eqtype only checks that incoming and result parameters match,
|
// eqtype only checks that incoming and result parameters match,
|
||||||
// so explicitly check that the receiver parameters match too.
|
// so explicitly check that the receiver parameters match too.
|
||||||
if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) {
|
if !eqtype(t, f.Type) || !eqtype(t.Recv().Type, f.Type.Recv().Type) {
|
||||||
Yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
|
yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -451,7 +451,7 @@ func escAnalyze(all []*Node, recursive bool) {
|
|||||||
e.theSink.Op = ONAME
|
e.theSink.Op = ONAME
|
||||||
e.theSink.Orig = &e.theSink
|
e.theSink.Orig = &e.theSink
|
||||||
e.theSink.Class = PEXTERN
|
e.theSink.Class = PEXTERN
|
||||||
e.theSink.Sym = Lookup(".sink")
|
e.theSink.Sym = lookup(".sink")
|
||||||
e.nodeEscState(&e.theSink).Escloopdepth = -1
|
e.nodeEscState(&e.theSink).Escloopdepth = -1
|
||||||
e.recursive = recursive
|
e.recursive = recursive
|
||||||
|
|
||||||
@ -1097,7 +1097,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
|
|||||||
a := Nod(OADDR, src, nil)
|
a := Nod(OADDR, src, nil)
|
||||||
a.Lineno = src.Lineno
|
a.Lineno = src.Lineno
|
||||||
e.nodeEscState(a).Escloopdepth = e.nodeEscState(src).Escloopdepth
|
e.nodeEscState(a).Escloopdepth = e.nodeEscState(src).Escloopdepth
|
||||||
a.Type = Ptrto(src.Type)
|
a.Type = ptrto(src.Type)
|
||||||
escflows(e, dst, a, e.stepAssign(nil, originalDst, src, dstwhy))
|
escflows(e, dst, a, e.stepAssign(nil, originalDst, src, dstwhy))
|
||||||
|
|
||||||
// Flowing multiple returns to a single dst happens when
|
// Flowing multiple returns to a single dst happens when
|
||||||
@ -1392,7 +1392,7 @@ func initEscretval(e *EscState, n *Node, fntype *Type) {
|
|||||||
src := Nod(ONAME, nil, nil)
|
src := Nod(ONAME, nil, nil)
|
||||||
buf := fmt.Sprintf(".out%d", i)
|
buf := fmt.Sprintf(".out%d", i)
|
||||||
i++
|
i++
|
||||||
src.Sym = Lookup(buf)
|
src.Sym = lookup(buf)
|
||||||
src.Type = t.Type
|
src.Type = t.Type
|
||||||
src.Class = PAUTO
|
src.Class = PAUTO
|
||||||
src.Name.Curfn = Curfn
|
src.Name.Curfn = Curfn
|
||||||
@ -1502,7 +1502,7 @@ func esccall(e *EscState, n *Node, up *Node) {
|
|||||||
// Introduce ODDDARG node to represent ... allocation.
|
// Introduce ODDDARG node to represent ... allocation.
|
||||||
src = Nod(ODDDARG, nil, nil)
|
src = Nod(ODDDARG, nil, nil)
|
||||||
arr := typArray(n2.Type.Elem(), int64(len(lls)))
|
arr := typArray(n2.Type.Elem(), int64(len(lls)))
|
||||||
src.Type = Ptrto(arr) // make pointer so it will be tracked
|
src.Type = ptrto(arr) // make pointer so it will be tracked
|
||||||
src.Lineno = n.Lineno
|
src.Lineno = n.Lineno
|
||||||
e.track(src)
|
e.track(src)
|
||||||
n.Right = src
|
n.Right = src
|
||||||
@ -1558,7 +1558,7 @@ func esccall(e *EscState, n *Node, up *Node) {
|
|||||||
note := ""
|
note := ""
|
||||||
i := 0
|
i := 0
|
||||||
lls := ll.Slice()
|
lls := ll.Slice()
|
||||||
for t, it := IterFields(fntype.Params()); i < len(lls); i++ {
|
for t, it := iterFields(fntype.Params()); i < len(lls); i++ {
|
||||||
src = lls[i]
|
src = lls[i]
|
||||||
note = t.Note
|
note = t.Note
|
||||||
if t.Isddd && !n.Isddd {
|
if t.Isddd && !n.Isddd {
|
||||||
@ -1566,7 +1566,7 @@ func esccall(e *EscState, n *Node, up *Node) {
|
|||||||
src = Nod(ODDDARG, nil, nil)
|
src = Nod(ODDDARG, nil, nil)
|
||||||
src.Lineno = n.Lineno
|
src.Lineno = n.Lineno
|
||||||
arr := typArray(t.Type.Elem(), int64(len(lls)-i))
|
arr := typArray(t.Type.Elem(), int64(len(lls)-i))
|
||||||
src.Type = Ptrto(arr) // make pointer so it will be tracked
|
src.Type = ptrto(arr) // make pointer so it will be tracked
|
||||||
e.track(src)
|
e.track(src)
|
||||||
n.Right = src
|
n.Right = src
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ func exportsym(n *Node) {
|
|||||||
}
|
}
|
||||||
if n.Sym.Flags&(SymExport|SymPackage) != 0 {
|
if n.Sym.Flags&(SymExport|SymPackage) != 0 {
|
||||||
if n.Sym.Flags&SymPackage != 0 {
|
if n.Sym.Flags&SymPackage != 0 {
|
||||||
Yyerror("export/package mismatch: %v", n.Sym)
|
yyerror("export/package mismatch: %v", n.Sym)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ func pkgtype(s *Sym) *Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if s.Def.Type == nil {
|
if s.Def.Type == nil {
|
||||||
Yyerror("pkgtype %v", s)
|
yyerror("pkgtype %v", s)
|
||||||
}
|
}
|
||||||
return s.Def.Type
|
return s.Def.Type
|
||||||
}
|
}
|
||||||
@ -306,7 +306,7 @@ func importconst(s *Sym, t *Type, n *Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n.Op != OLITERAL {
|
if n.Op != OLITERAL {
|
||||||
Yyerror("expression must be a constant")
|
yyerror("expression must be a constant")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +331,7 @@ func importvar(s *Sym, t *Type) {
|
|||||||
if eqtype(t, s.Def.Type) {
|
if eqtype(t, s.Def.Type) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Yyerror("inconsistent definition for var %v during import\n\t%v (in %q)\n\t%v (in %q)", s, s.Def.Type, s.Importdef.Path, t, importpkg.Path)
|
yyerror("inconsistent definition for var %v during import\n\t%v (in %q)\n\t%v (in %q)", s, s.Def.Type, s.Importdef.Path, t, importpkg.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
n := newname(s)
|
n := newname(s)
|
||||||
|
@ -738,7 +738,7 @@ func (t *Type) typefmt(flag FmtFlag) string {
|
|||||||
return "map.iter[" + m.Key().String() + "]" + m.Val().String()
|
return "map.iter[" + m.Key().String() + "]" + m.Val().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
Yyerror("unknown internal map type")
|
yyerror("unknown internal map type")
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := make([]byte, 0, 64)
|
buf := make([]byte, 0, 64)
|
||||||
@ -752,7 +752,7 @@ func (t *Type) typefmt(flag FmtFlag) string {
|
|||||||
if i != 0 {
|
if i != 0 {
|
||||||
buf = append(buf, ", "...)
|
buf = append(buf, ", "...)
|
||||||
}
|
}
|
||||||
buf = append(buf, Fldconv(f, flag1)...)
|
buf = append(buf, fldconv(f, flag1)...)
|
||||||
}
|
}
|
||||||
buf = append(buf, ')')
|
buf = append(buf, ')')
|
||||||
} else {
|
} else {
|
||||||
@ -762,7 +762,7 @@ func (t *Type) typefmt(flag FmtFlag) string {
|
|||||||
buf = append(buf, ';')
|
buf = append(buf, ';')
|
||||||
}
|
}
|
||||||
buf = append(buf, ' ')
|
buf = append(buf, ' ')
|
||||||
buf = append(buf, Fldconv(f, FmtLong)...)
|
buf = append(buf, fldconv(f, FmtLong)...)
|
||||||
}
|
}
|
||||||
if t.NumFields() != 0 {
|
if t.NumFields() != 0 {
|
||||||
buf = append(buf, ' ')
|
buf = append(buf, ' ')
|
||||||
@ -1600,7 +1600,7 @@ func (t *Type) String() string {
|
|||||||
return t.tconv(0)
|
return t.tconv(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fldconv(f *Field, flag FmtFlag) string {
|
func fldconv(f *Field, flag FmtFlag) string {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return "<T>"
|
return "<T>"
|
||||||
}
|
}
|
||||||
@ -1628,7 +1628,7 @@ func Fldconv(f *Field, flag FmtFlag) string {
|
|||||||
if s.Name[1] == 'r' { // originally an unnamed result
|
if s.Name[1] == 'r' { // originally an unnamed result
|
||||||
s = nil
|
s = nil
|
||||||
} else if s.Name[1] == 'b' { // originally the blank identifier _
|
} else if s.Name[1] == 'b' { // originally the blank identifier _
|
||||||
s = Lookup("_")
|
s = lookup("_")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,7 +105,7 @@ func moveToHeap(n *Node) {
|
|||||||
Dump("MOVE", n)
|
Dump("MOVE", n)
|
||||||
}
|
}
|
||||||
if compiling_runtime {
|
if compiling_runtime {
|
||||||
Yyerror("%v escapes to heap, not allowed in runtime.", n)
|
yyerror("%v escapes to heap, not allowed in runtime.", n)
|
||||||
}
|
}
|
||||||
if n.Class == PAUTOHEAP {
|
if n.Class == PAUTOHEAP {
|
||||||
Dump("n", n)
|
Dump("n", n)
|
||||||
@ -114,8 +114,8 @@ func moveToHeap(n *Node) {
|
|||||||
|
|
||||||
// Allocate a local stack variable to hold the pointer to the heap copy.
|
// Allocate a local stack variable to hold the pointer to the heap copy.
|
||||||
// temp will add it to the function declaration list automatically.
|
// temp will add it to the function declaration list automatically.
|
||||||
heapaddr := temp(Ptrto(n.Type))
|
heapaddr := temp(ptrto(n.Type))
|
||||||
heapaddr.Sym = Lookup("&" + n.Sym.Name)
|
heapaddr.Sym = lookup("&" + n.Sym.Name)
|
||||||
heapaddr.Orig.Sym = heapaddr.Sym
|
heapaddr.Orig.Sym = heapaddr.Sym
|
||||||
|
|
||||||
// Parameters have a local stack copy used at function start/end
|
// Parameters have a local stack copy used at function start/end
|
||||||
@ -200,13 +200,13 @@ func tempname(nn *Node, t *Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if t == nil {
|
if t == nil {
|
||||||
Yyerror("tempname called with nil type")
|
yyerror("tempname called with nil type")
|
||||||
t = Types[TINT32]
|
t = Types[TINT32]
|
||||||
}
|
}
|
||||||
|
|
||||||
// give each tmp a different name so that there
|
// give each tmp a different name so that there
|
||||||
// a chance to registerizer them
|
// a chance to registerizer them
|
||||||
s := LookupN("autotmp_", statuniqgen)
|
s := lookupN("autotmp_", statuniqgen)
|
||||||
statuniqgen++
|
statuniqgen++
|
||||||
n := Nod(ONAME, nil, nil)
|
n := Nod(ONAME, nil, nil)
|
||||||
n.Sym = s
|
n.Sym = s
|
||||||
|
@ -286,7 +286,7 @@ func Naddr(a *obj.Addr, n *Node) {
|
|||||||
a.Sym = Linksym(n.Sym)
|
a.Sym = Linksym(n.Sym)
|
||||||
a.Offset = n.Xoffset
|
a.Offset = n.Xoffset
|
||||||
if a.Offset != int64(int32(a.Offset)) {
|
if a.Offset != int64(int32(a.Offset)) {
|
||||||
Yyerror("offset %d too large for OINDREG", a.Offset)
|
yyerror("offset %d too large for OINDREG", a.Offset)
|
||||||
}
|
}
|
||||||
if Thearch.LinkArch.Family == sys.I386 { // TODO(rsc): Never clear a->width.
|
if Thearch.LinkArch.Family == sys.I386 { // TODO(rsc): Never clear a->width.
|
||||||
a.Width = 0
|
a.Width = 0
|
||||||
@ -317,7 +317,7 @@ func Naddr(a *obj.Addr, n *Node) {
|
|||||||
//if(a->node >= (Node*)&n)
|
//if(a->node >= (Node*)&n)
|
||||||
// fatal("stack node");
|
// fatal("stack node");
|
||||||
if s == nil {
|
if s == nil {
|
||||||
s = Lookup(".noname")
|
s = lookup(".noname")
|
||||||
}
|
}
|
||||||
if n.Name.Method && n.Type != nil && n.Type.Sym != nil && n.Type.Sym.Pkg != nil {
|
if n.Name.Method && n.Type != nil && n.Type.Sym != nil && n.Type.Sym.Pkg != nil {
|
||||||
s = Pkglookup(s.Name, n.Type.Sym.Pkg)
|
s = Pkglookup(s.Name, n.Type.Sym.Pkg)
|
||||||
@ -503,7 +503,7 @@ func nodarg(t interface{}, fp int) *Node {
|
|||||||
|
|
||||||
// Build fake variable name for whole arg struct.
|
// Build fake variable name for whole arg struct.
|
||||||
n = Nod(ONAME, nil, nil)
|
n = Nod(ONAME, nil, nil)
|
||||||
n.Sym = Lookup(".args")
|
n.Sym = lookup(".args")
|
||||||
n.Type = t
|
n.Type = t
|
||||||
first := t.Field(0)
|
first := t.Field(0)
|
||||||
if first == nil {
|
if first == nil {
|
||||||
@ -566,7 +566,7 @@ func nodarg(t interface{}, fp int) *Node {
|
|||||||
// or else the assignment to _ will be
|
// or else the assignment to _ will be
|
||||||
// discarded during code generation.
|
// discarded during code generation.
|
||||||
if isblank(n) {
|
if isblank(n) {
|
||||||
n.Sym = Lookup("__")
|
n.Sym = lookup("__")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch fp {
|
switch fp {
|
||||||
@ -648,7 +648,7 @@ Switch:
|
|||||||
break Switch
|
break Switch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
regdump()
|
regdump()
|
||||||
Fatalf("out of fixed registers")
|
Fatalf("out of fixed registers")
|
||||||
|
|
||||||
@ -668,7 +668,7 @@ Switch:
|
|||||||
break Switch
|
break Switch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
regdump()
|
regdump()
|
||||||
Fatalf("out of floating registers")
|
Fatalf("out of floating registers")
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ var renameinit_initgen int
|
|||||||
|
|
||||||
func renameinit() *Sym {
|
func renameinit() *Sym {
|
||||||
renameinit_initgen++
|
renameinit_initgen++
|
||||||
return LookupN("init.", renameinit_initgen)
|
return lookupN("init.", renameinit_initgen)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hand-craft the following initialization code
|
// hand-craft the following initialization code
|
||||||
@ -70,7 +70,7 @@ func anyinit(n []*Node) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// is there an explicit init function
|
// is there an explicit init function
|
||||||
s := Lookup("init.1")
|
s := lookup("init.1")
|
||||||
|
|
||||||
if s.Def != nil {
|
if s.Def != nil {
|
||||||
return true
|
return true
|
||||||
@ -101,14 +101,14 @@ func fninit(n []*Node) {
|
|||||||
var r []*Node
|
var r []*Node
|
||||||
|
|
||||||
// (1)
|
// (1)
|
||||||
gatevar := newname(Lookup("initdone·"))
|
gatevar := newname(lookup("initdone·"))
|
||||||
addvar(gatevar, Types[TUINT8], PEXTERN)
|
addvar(gatevar, Types[TUINT8], PEXTERN)
|
||||||
|
|
||||||
// (2)
|
// (2)
|
||||||
Maxarg = 0
|
Maxarg = 0
|
||||||
|
|
||||||
fn := Nod(ODCLFUNC, nil, nil)
|
fn := Nod(ODCLFUNC, nil, nil)
|
||||||
initsym := Lookup("init")
|
initsym := lookup("init")
|
||||||
fn.Func.Nname = newname(initsym)
|
fn.Func.Nname = newname(initsym)
|
||||||
fn.Func.Nname.Name.Defn = fn
|
fn.Func.Nname.Name.Defn = fn
|
||||||
fn.Func.Nname.Name.Param.Ntype = Nod(OTFUNC, nil, nil)
|
fn.Func.Nname.Name.Param.Ntype = Nod(OTFUNC, nil, nil)
|
||||||
@ -153,7 +153,7 @@ func fninit(n []*Node) {
|
|||||||
// (8)
|
// (8)
|
||||||
// could check that it is fn of no args/returns
|
// could check that it is fn of no args/returns
|
||||||
for i := 1; ; i++ {
|
for i := 1; ; i++ {
|
||||||
s := LookupN("init.", i)
|
s := lookupN("init.", i)
|
||||||
if s.Def == nil {
|
if s.Def == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -722,7 +722,7 @@ func mkinlcall1(n *Node, fn *Node, isddd bool) *Node {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// match arguments except final variadic (unless the call is dotted itself)
|
// match arguments except final variadic (unless the call is dotted itself)
|
||||||
t, it := IterFields(fn.Type.Params())
|
t, it := iterFields(fn.Type.Params())
|
||||||
for t != nil {
|
for t != nil {
|
||||||
if li >= n.List.Len() {
|
if li >= n.List.Len() {
|
||||||
break
|
break
|
||||||
@ -870,7 +870,7 @@ func inlvar(var_ *Node) *Node {
|
|||||||
|
|
||||||
// Synthesize a variable to store the inlined function's results in.
|
// Synthesize a variable to store the inlined function's results in.
|
||||||
func retvar(t *Field, i int) *Node {
|
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.Used = true
|
||||||
@ -882,7 +882,7 @@ func retvar(t *Field, i int) *Node {
|
|||||||
// Synthesize a variable to store the inlined function's arguments
|
// Synthesize a variable to store the inlined function's arguments
|
||||||
// when they come from a multiple return call.
|
// when they come from a multiple return call.
|
||||||
func argvar(t *Type, i int) *Node {
|
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.Used = true
|
||||||
@ -969,7 +969,7 @@ func (subst *inlsubst) node(n *Node) *Node {
|
|||||||
*m = *n
|
*m = *n
|
||||||
m.Ninit.Set(nil)
|
m.Ninit.Set(nil)
|
||||||
p := fmt.Sprintf("%s·%d", n.Left.Sym.Name, inlgen)
|
p := fmt.Sprintf("%s·%d", n.Left.Sym.Name, inlgen)
|
||||||
m.Left = newname(Lookup(p))
|
m.Left = newname(lookup(p))
|
||||||
|
|
||||||
return m
|
return m
|
||||||
default:
|
default:
|
||||||
|
@ -76,7 +76,7 @@ const (
|
|||||||
UintptrEscapes // pointers converted to uintptr escape
|
UintptrEscapes // pointers converted to uintptr escape
|
||||||
)
|
)
|
||||||
|
|
||||||
func PragmaValue(verb string) Pragma {
|
func pragmaValue(verb string) Pragma {
|
||||||
switch verb {
|
switch verb {
|
||||||
case "go:nointerface":
|
case "go:nointerface":
|
||||||
if obj.Fieldtrack_enabled != 0 {
|
if obj.Fieldtrack_enabled != 0 {
|
||||||
@ -92,17 +92,17 @@ func PragmaValue(verb string) Pragma {
|
|||||||
return Noinline
|
return Noinline
|
||||||
case "go:systemstack":
|
case "go:systemstack":
|
||||||
if !compiling_runtime {
|
if !compiling_runtime {
|
||||||
Yyerror("//go:systemstack only allowed in runtime")
|
yyerror("//go:systemstack only allowed in runtime")
|
||||||
}
|
}
|
||||||
return Systemstack
|
return Systemstack
|
||||||
case "go:nowritebarrier":
|
case "go:nowritebarrier":
|
||||||
if !compiling_runtime {
|
if !compiling_runtime {
|
||||||
Yyerror("//go:nowritebarrier only allowed in runtime")
|
yyerror("//go:nowritebarrier only allowed in runtime")
|
||||||
}
|
}
|
||||||
return Nowritebarrier
|
return Nowritebarrier
|
||||||
case "go:nowritebarrierrec":
|
case "go:nowritebarrierrec":
|
||||||
if !compiling_runtime {
|
if !compiling_runtime {
|
||||||
Yyerror("//go:nowritebarrierrec only allowed in runtime")
|
yyerror("//go:nowritebarrierrec only allowed in runtime")
|
||||||
}
|
}
|
||||||
return Nowritebarrierrec | Nowritebarrier // implies Nowritebarrier
|
return Nowritebarrierrec | Nowritebarrier // implies Nowritebarrier
|
||||||
case "go:cgo_unsafe_args":
|
case "go:cgo_unsafe_args":
|
||||||
@ -355,7 +355,7 @@ l0:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if c == EOF {
|
if c == EOF {
|
||||||
Yyerror("eof in comment")
|
yyerror("eof in comment")
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
c = l.getr()
|
c = l.getr()
|
||||||
@ -520,7 +520,7 @@ l0:
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
// anything else is illegal
|
// anything else is illegal
|
||||||
Yyerror("syntax error: illegal character %#U", c)
|
yyerror("syntax error: illegal character %#U", c)
|
||||||
goto l0
|
goto l0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,10 +581,10 @@ func (l *lexer) ident(c rune) {
|
|||||||
if c >= utf8.RuneSelf {
|
if c >= utf8.RuneSelf {
|
||||||
if unicode.IsLetter(c) || c == '_' || unicode.IsDigit(c) {
|
if unicode.IsLetter(c) || c == '_' || unicode.IsDigit(c) {
|
||||||
if cp.Len() == 0 && unicode.IsDigit(c) {
|
if cp.Len() == 0 && unicode.IsDigit(c) {
|
||||||
Yyerror("identifier cannot begin with digit %#U", c)
|
yyerror("identifier cannot begin with digit %#U", c)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Yyerror("invalid identifier character %#U", c)
|
yyerror("invalid identifier character %#U", c)
|
||||||
}
|
}
|
||||||
cp.WriteRune(c)
|
cp.WriteRune(c)
|
||||||
} else if isLetter(c) || isDigit(c) {
|
} else if isLetter(c) || isDigit(c) {
|
||||||
@ -614,7 +614,7 @@ func (l *lexer) ident(c rune) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s := LookupBytes(name)
|
s := lookupBytes(name)
|
||||||
if Debug['x'] != 0 {
|
if Debug['x'] != 0 {
|
||||||
fmt.Printf("lex: ident %v\n", s)
|
fmt.Printf("lex: ident %v\n", s)
|
||||||
}
|
}
|
||||||
@ -686,7 +686,7 @@ func (l *lexer) number(c rune) {
|
|||||||
c = l.getr()
|
c = l.getr()
|
||||||
}
|
}
|
||||||
if lexbuf.Len() == 2 {
|
if lexbuf.Len() == 2 {
|
||||||
Yyerror("malformed hex constant")
|
yyerror("malformed hex constant")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// decimal 0, octal, or float
|
// decimal 0, octal, or float
|
||||||
@ -727,7 +727,7 @@ func (l *lexer) number(c rune) {
|
|||||||
c = l.getr()
|
c = l.getr()
|
||||||
}
|
}
|
||||||
if !isDigit(c) {
|
if !isDigit(c) {
|
||||||
Yyerror("malformed floating point constant exponent")
|
yyerror("malformed floating point constant exponent")
|
||||||
}
|
}
|
||||||
for isDigit(c) {
|
for isDigit(c) {
|
||||||
cp.WriteByte(byte(c))
|
cp.WriteByte(byte(c))
|
||||||
@ -742,7 +742,7 @@ func (l *lexer) number(c rune) {
|
|||||||
x.Real.SetFloat64(0.0)
|
x.Real.SetFloat64(0.0)
|
||||||
x.Imag.SetString(str)
|
x.Imag.SetString(str)
|
||||||
if x.Imag.Val.IsInf() {
|
if x.Imag.Val.IsInf() {
|
||||||
Yyerror("overflow in imaginary constant")
|
yyerror("overflow in imaginary constant")
|
||||||
x.Imag.SetFloat64(0.0)
|
x.Imag.SetFloat64(0.0)
|
||||||
}
|
}
|
||||||
l.val.U = x
|
l.val.U = x
|
||||||
@ -758,14 +758,14 @@ func (l *lexer) number(c rune) {
|
|||||||
|
|
||||||
if isInt {
|
if isInt {
|
||||||
if malformedOctal {
|
if malformedOctal {
|
||||||
Yyerror("malformed octal constant")
|
yyerror("malformed octal constant")
|
||||||
}
|
}
|
||||||
|
|
||||||
str = lexbuf.String()
|
str = lexbuf.String()
|
||||||
x := new(Mpint)
|
x := new(Mpint)
|
||||||
x.SetString(str)
|
x.SetString(str)
|
||||||
if x.Ovf {
|
if x.Ovf {
|
||||||
Yyerror("overflow in constant")
|
yyerror("overflow in constant")
|
||||||
x.SetInt64(0)
|
x.SetInt64(0)
|
||||||
}
|
}
|
||||||
l.val.U = x
|
l.val.U = x
|
||||||
@ -780,7 +780,7 @@ func (l *lexer) number(c rune) {
|
|||||||
x := newMpflt()
|
x := newMpflt()
|
||||||
x.SetString(str)
|
x.SetString(str)
|
||||||
if x.Val.IsInf() {
|
if x.Val.IsInf() {
|
||||||
Yyerror("overflow in float constant")
|
yyerror("overflow in float constant")
|
||||||
x.SetFloat64(0.0)
|
x.SetFloat64(0.0)
|
||||||
}
|
}
|
||||||
l.val.U = x
|
l.val.U = x
|
||||||
@ -837,7 +837,7 @@ func (l *lexer) rawString() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if c == EOF {
|
if c == EOF {
|
||||||
Yyerror("eof in string")
|
yyerror("eof in string")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if c == '`' {
|
if c == '`' {
|
||||||
@ -858,7 +858,7 @@ func (l *lexer) rawString() {
|
|||||||
func (l *lexer) rune() {
|
func (l *lexer) rune() {
|
||||||
r, b, ok := l.onechar('\'')
|
r, b, ok := l.onechar('\'')
|
||||||
if !ok {
|
if !ok {
|
||||||
Yyerror("empty character literal or unescaped ' in character literal")
|
yyerror("empty character literal or unescaped ' in character literal")
|
||||||
r = '\''
|
r = '\''
|
||||||
}
|
}
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
@ -866,7 +866,7 @@ func (l *lexer) rune() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if c := l.getr(); c != '\'' {
|
if c := l.getr(); c != '\'' {
|
||||||
Yyerror("missing '")
|
yyerror("missing '")
|
||||||
l.ungetr()
|
l.ungetr()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -929,16 +929,16 @@ func (l *lexer) getlinepragma() rune {
|
|||||||
switch verb {
|
switch verb {
|
||||||
case "go:linkname":
|
case "go:linkname":
|
||||||
if !imported_unsafe {
|
if !imported_unsafe {
|
||||||
Yyerror("//go:linkname only allowed in Go files that import \"unsafe\"")
|
yyerror("//go:linkname only allowed in Go files that import \"unsafe\"")
|
||||||
}
|
}
|
||||||
f := strings.Fields(text)
|
f := strings.Fields(text)
|
||||||
if len(f) != 3 {
|
if len(f) != 3 {
|
||||||
Yyerror("usage: //go:linkname localname linkname")
|
yyerror("usage: //go:linkname localname linkname")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
Lookup(f[1]).Linkname = f[2]
|
lookup(f[1]).Linkname = f[2]
|
||||||
default:
|
default:
|
||||||
l.pragma |= PragmaValue(verb)
|
l.pragma |= pragmaValue(verb)
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@ -984,7 +984,7 @@ func (l *lexer) getlinepragma() rune {
|
|||||||
return c // todo: make this an error instead? it is almost certainly a bug.
|
return c // todo: make this an error instead? it is almost certainly a bug.
|
||||||
}
|
}
|
||||||
if n > 1e8 {
|
if n > 1e8 {
|
||||||
Yyerror("line number out of range")
|
yyerror("line number out of range")
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
if n <= 0 {
|
if n <= 0 {
|
||||||
@ -1012,7 +1012,7 @@ func pragcgo(text string) string {
|
|||||||
return fmt.Sprintln(verb, local, remote)
|
return fmt.Sprintln(verb, local, remote)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Yyerror(`usage: //go:%s local [remote]`, verb)
|
yyerror(`usage: //go:%s local [remote]`, verb)
|
||||||
}
|
}
|
||||||
case "cgo_import_dynamic":
|
case "cgo_import_dynamic":
|
||||||
switch {
|
switch {
|
||||||
@ -1032,7 +1032,7 @@ func pragcgo(text string) string {
|
|||||||
return fmt.Sprintln(verb, local, remote, library)
|
return fmt.Sprintln(verb, local, remote, library)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Yyerror(`usage: //go:cgo_import_dynamic local [remote ["library"]]`)
|
yyerror(`usage: //go:cgo_import_dynamic local [remote ["library"]]`)
|
||||||
}
|
}
|
||||||
case "cgo_import_static":
|
case "cgo_import_static":
|
||||||
switch {
|
switch {
|
||||||
@ -1041,7 +1041,7 @@ func pragcgo(text string) string {
|
|||||||
return fmt.Sprintln(verb, local)
|
return fmt.Sprintln(verb, local)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Yyerror(`usage: //go:cgo_import_static local`)
|
yyerror(`usage: //go:cgo_import_static local`)
|
||||||
}
|
}
|
||||||
case "cgo_dynamic_linker":
|
case "cgo_dynamic_linker":
|
||||||
switch {
|
switch {
|
||||||
@ -1050,7 +1050,7 @@ func pragcgo(text string) string {
|
|||||||
return fmt.Sprintln(verb, path)
|
return fmt.Sprintln(verb, path)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Yyerror(`usage: //go:cgo_dynamic_linker "path"`)
|
yyerror(`usage: //go:cgo_dynamic_linker "path"`)
|
||||||
}
|
}
|
||||||
case "cgo_ldflag":
|
case "cgo_ldflag":
|
||||||
switch {
|
switch {
|
||||||
@ -1059,7 +1059,7 @@ func pragcgo(text string) string {
|
|||||||
return fmt.Sprintln(verb, arg)
|
return fmt.Sprintln(verb, arg)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Yyerror(`usage: //go:cgo_ldflag "arg"`)
|
yyerror(`usage: //go:cgo_ldflag "arg"`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
@ -1143,12 +1143,12 @@ func (l *lexer) onechar(quote rune) (r rune, b byte, ok bool) {
|
|||||||
c := l.getr()
|
c := l.getr()
|
||||||
switch c {
|
switch c {
|
||||||
case EOF:
|
case EOF:
|
||||||
Yyerror("eof in string")
|
yyerror("eof in string")
|
||||||
l.ungetr()
|
l.ungetr()
|
||||||
return
|
return
|
||||||
|
|
||||||
case '\n':
|
case '\n':
|
||||||
Yyerror("newline in string")
|
yyerror("newline in string")
|
||||||
l.ungetr()
|
l.ungetr()
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -1182,12 +1182,12 @@ func (l *lexer) onechar(quote rune) (r rune, b byte, ok bool) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
Yyerror("non-octal character in escape sequence: %c", c)
|
yyerror("non-octal character in escape sequence: %c", c)
|
||||||
l.ungetr()
|
l.ungetr()
|
||||||
}
|
}
|
||||||
|
|
||||||
if x > 255 {
|
if x > 255 {
|
||||||
Yyerror("octal escape value > 255: %d", x)
|
yyerror("octal escape value > 255: %d", x)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, byte(x), true
|
return 0, byte(x), true
|
||||||
@ -1211,7 +1211,7 @@ func (l *lexer) onechar(quote rune) (r rune, b byte, ok bool) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if c != quote {
|
if c != quote {
|
||||||
Yyerror("unknown escape sequence: %c", c)
|
yyerror("unknown escape sequence: %c", c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1221,7 +1221,7 @@ func (l *lexer) onechar(quote rune) (r rune, b byte, ok bool) {
|
|||||||
func (l *lexer) unichar(n int) rune {
|
func (l *lexer) unichar(n int) rune {
|
||||||
x := l.hexchar(n)
|
x := l.hexchar(n)
|
||||||
if x > utf8.MaxRune || 0xd800 <= x && x < 0xe000 {
|
if x > utf8.MaxRune || 0xd800 <= x && x < 0xe000 {
|
||||||
Yyerror("invalid Unicode code point in escape sequence: %#x", x)
|
yyerror("invalid Unicode code point in escape sequence: %#x", x)
|
||||||
x = utf8.RuneError
|
x = utf8.RuneError
|
||||||
}
|
}
|
||||||
return rune(x)
|
return rune(x)
|
||||||
@ -1240,7 +1240,7 @@ func (l *lexer) hexchar(n int) uint32 {
|
|||||||
case 'A' <= c && c <= 'F':
|
case 'A' <= c && c <= 'F':
|
||||||
d = uint32(c - 'A' + 10)
|
d = uint32(c - 'A' + 10)
|
||||||
default:
|
default:
|
||||||
Yyerror("non-hex character in escape sequence: %c", c)
|
yyerror("non-hex character in escape sequence: %c", c)
|
||||||
l.ungetr()
|
l.ungetr()
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ func Main() {
|
|||||||
defer hidePanic()
|
defer hidePanic()
|
||||||
|
|
||||||
Ctxt = obj.Linknew(Thearch.LinkArch)
|
Ctxt = obj.Linknew(Thearch.LinkArch)
|
||||||
Ctxt.DiagFunc = Yyerror
|
Ctxt.DiagFunc = yyerror
|
||||||
Ctxt.Bso = bufio.NewWriter(os.Stdout)
|
Ctxt.Bso = bufio.NewWriter(os.Stdout)
|
||||||
|
|
||||||
localpkg = mkpkg("")
|
localpkg = mkpkg("")
|
||||||
@ -506,7 +506,7 @@ func Main() {
|
|||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
timings.Stop()
|
timings.Stop()
|
||||||
|
|
||||||
if benchfile != "" {
|
if benchfile != "" {
|
||||||
@ -631,7 +631,7 @@ func findpkg(name string) (file string, ok bool) {
|
|||||||
// don't want to see "encoding/../encoding/base64"
|
// don't want to see "encoding/../encoding/base64"
|
||||||
// as different from "encoding/base64".
|
// as different from "encoding/base64".
|
||||||
if q := path.Clean(name); q != name {
|
if q := path.Clean(name); q != name {
|
||||||
Yyerror("non-canonical import path %q (should be %q)", name, q)
|
yyerror("non-canonical import path %q (should be %q)", name, q)
|
||||||
return "", false
|
return "", false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,12 +698,12 @@ func importfile(f *Val, indent []byte) {
|
|||||||
|
|
||||||
path_, ok := f.U.(string)
|
path_, ok := f.U.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
Yyerror("import statement not a string")
|
yyerror("import statement not a string")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(path_) == 0 {
|
if len(path_) == 0 {
|
||||||
Yyerror("import path is empty")
|
yyerror("import path is empty")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,12 +716,12 @@ func importfile(f *Val, indent []byte) {
|
|||||||
// the main package, just as we reserve the import
|
// the main package, just as we reserve the import
|
||||||
// path "math" to identify the standard math package.
|
// path "math" to identify the standard math package.
|
||||||
if path_ == "main" {
|
if path_ == "main" {
|
||||||
Yyerror("cannot import \"main\"")
|
yyerror("cannot import \"main\"")
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
if myimportpath != "" && path_ == myimportpath {
|
if myimportpath != "" && path_ == myimportpath {
|
||||||
Yyerror("import %q while compiling that package (import cycle)", path_)
|
yyerror("import %q while compiling that package (import cycle)", path_)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,7 +731,7 @@ func importfile(f *Val, indent []byte) {
|
|||||||
|
|
||||||
if path_ == "unsafe" {
|
if path_ == "unsafe" {
|
||||||
if safemode {
|
if safemode {
|
||||||
Yyerror("cannot import package unsafe")
|
yyerror("cannot import package unsafe")
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,7 +742,7 @@ func importfile(f *Val, indent []byte) {
|
|||||||
|
|
||||||
if islocalname(path_) {
|
if islocalname(path_) {
|
||||||
if path_[0] == '/' {
|
if path_[0] == '/' {
|
||||||
Yyerror("import path cannot be absolute path")
|
yyerror("import path cannot be absolute path")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -759,7 +759,7 @@ func importfile(f *Val, indent []byte) {
|
|||||||
|
|
||||||
file, found := findpkg(path_)
|
file, found := findpkg(path_)
|
||||||
if !found {
|
if !found {
|
||||||
Yyerror("can't find import: %q", path_)
|
yyerror("can't find import: %q", path_)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,7 +773,7 @@ func importfile(f *Val, indent []byte) {
|
|||||||
|
|
||||||
impf, err := os.Open(file)
|
impf, err := os.Open(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Yyerror("can't open import: %q: %v", path_, err)
|
yyerror("can't open import: %q: %v", path_, err)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
defer impf.Close()
|
defer impf.Close()
|
||||||
@ -781,7 +781,7 @@ func importfile(f *Val, indent []byte) {
|
|||||||
|
|
||||||
if strings.HasSuffix(file, ".a") {
|
if strings.HasSuffix(file, ".a") {
|
||||||
if !skiptopkgdef(imp) {
|
if !skiptopkgdef(imp) {
|
||||||
Yyerror("import %s: not a package file", file)
|
yyerror("import %s: not a package file", file)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -797,13 +797,13 @@ func importfile(f *Val, indent []byte) {
|
|||||||
|
|
||||||
if p != "empty archive" {
|
if p != "empty archive" {
|
||||||
if !strings.HasPrefix(p, "go object ") {
|
if !strings.HasPrefix(p, "go object ") {
|
||||||
Yyerror("import %s: not a go object file: %s", file, p)
|
yyerror("import %s: not a go object file: %s", file, p)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
q := fmt.Sprintf("%s %s %s %s", obj.GOOS, obj.GOARCH, obj.Version, obj.Expstring())
|
q := fmt.Sprintf("%s %s %s %s", obj.GOOS, obj.GOARCH, obj.Version, obj.Expstring())
|
||||||
if p[10:] != q {
|
if p[10:] != q {
|
||||||
Yyerror("import %s: object is [%s] expected [%s]", file, p[10:], q)
|
yyerror("import %s: object is [%s] expected [%s]", file, p[10:], q)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -824,7 +824,7 @@ func importfile(f *Val, indent []byte) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if safemode && !safe {
|
if safemode && !safe {
|
||||||
Yyerror("cannot import unsafe package %q", importpkg.Path)
|
yyerror("cannot import unsafe package %q", importpkg.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume files move (get installed)
|
// assume files move (get installed)
|
||||||
@ -857,7 +857,7 @@ func importfile(f *Val, indent []byte) {
|
|||||||
|
|
||||||
switch c {
|
switch c {
|
||||||
case '\n':
|
case '\n':
|
||||||
Yyerror("cannot import %s: old export format no longer supported (recompile library)", path_)
|
yyerror("cannot import %s: old export format no longer supported (recompile library)", path_)
|
||||||
|
|
||||||
case 'B':
|
case 'B':
|
||||||
if Debug_export != 0 {
|
if Debug_export != 0 {
|
||||||
@ -867,7 +867,7 @@ func importfile(f *Val, indent []byte) {
|
|||||||
Import(imp)
|
Import(imp)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Yyerror("no import in %q", path_)
|
yyerror("no import in %q", path_)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -893,12 +893,12 @@ func pkgnotused(lineno int32, path string, name string) {
|
|||||||
func mkpackage(pkgname string) {
|
func mkpackage(pkgname string) {
|
||||||
if localpkg.Name == "" {
|
if localpkg.Name == "" {
|
||||||
if pkgname == "_" {
|
if pkgname == "_" {
|
||||||
Yyerror("invalid package name _")
|
yyerror("invalid package name _")
|
||||||
}
|
}
|
||||||
localpkg.Name = pkgname
|
localpkg.Name = pkgname
|
||||||
} else {
|
} else {
|
||||||
if pkgname != localpkg.Name {
|
if pkgname != localpkg.Name {
|
||||||
Yyerror("package %s; expected %s", pkgname, localpkg.Name)
|
yyerror("package %s; expected %s", pkgname, localpkg.Name)
|
||||||
}
|
}
|
||||||
for _, s := range localpkg.Syms {
|
for _, s := range localpkg.Syms {
|
||||||
if s.Def == nil {
|
if s.Def == nil {
|
||||||
|
@ -128,7 +128,7 @@ func (a *Mpflt) Float64() float64 {
|
|||||||
|
|
||||||
// check for overflow
|
// check for overflow
|
||||||
if math.IsInf(x, 0) && nsavederrors+nerrors == 0 {
|
if math.IsInf(x, 0) && nsavederrors+nerrors == 0 {
|
||||||
Yyerror("mpgetflt ovf")
|
yyerror("mpgetflt ovf")
|
||||||
}
|
}
|
||||||
|
|
||||||
return x + 0 // avoid -0 (should not be needed, but be conservative)
|
return x + 0 // avoid -0 (should not be needed, but be conservative)
|
||||||
@ -140,7 +140,7 @@ func (a *Mpflt) Float32() float64 {
|
|||||||
|
|
||||||
// check for overflow
|
// check for overflow
|
||||||
if math.IsInf(x, 0) && nsavederrors+nerrors == 0 {
|
if math.IsInf(x, 0) && nsavederrors+nerrors == 0 {
|
||||||
Yyerror("mpgetflt32 ovf")
|
yyerror("mpgetflt32 ovf")
|
||||||
}
|
}
|
||||||
|
|
||||||
return x + 0 // avoid -0 (should not be needed, but be conservative)
|
return x + 0 // avoid -0 (should not be needed, but be conservative)
|
||||||
@ -187,13 +187,13 @@ func (a *Mpflt) SetString(as string) {
|
|||||||
// - constant exponent out of range
|
// - constant exponent out of range
|
||||||
// - decimal point and binary point in constant
|
// - decimal point and binary point in constant
|
||||||
// TODO(gri) use different conversion function or check separately
|
// TODO(gri) use different conversion function or check separately
|
||||||
Yyerror("malformed constant: %s", as)
|
yyerror("malformed constant: %s", as)
|
||||||
a.Val.SetFloat64(0)
|
a.Val.SetFloat64(0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if f.IsInf() {
|
if f.IsInf() {
|
||||||
Yyerror("constant too large: %s", as)
|
yyerror("constant too large: %s", as)
|
||||||
a.Val.SetFloat64(0)
|
a.Val.SetFloat64(0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ func (a *Mpint) SetFloat(b *Mpflt) int {
|
|||||||
func (a *Mpint) Add(b *Mpint) {
|
func (a *Mpint) Add(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mpaddfixfix")
|
yyerror("ovf in mpaddfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -80,14 +80,14 @@ func (a *Mpint) Add(b *Mpint) {
|
|||||||
a.Val.Add(&a.Val, &b.Val)
|
a.Val.Add(&a.Val, &b.Val)
|
||||||
|
|
||||||
if a.checkOverflow(0) {
|
if a.checkOverflow(0) {
|
||||||
Yyerror("constant addition overflow")
|
yyerror("constant addition overflow")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Mpint) Sub(b *Mpint) {
|
func (a *Mpint) Sub(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mpsubfixfix")
|
yyerror("ovf in mpsubfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -96,14 +96,14 @@ func (a *Mpint) Sub(b *Mpint) {
|
|||||||
a.Val.Sub(&a.Val, &b.Val)
|
a.Val.Sub(&a.Val, &b.Val)
|
||||||
|
|
||||||
if a.checkOverflow(0) {
|
if a.checkOverflow(0) {
|
||||||
Yyerror("constant subtraction overflow")
|
yyerror("constant subtraction overflow")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Mpint) Mul(b *Mpint) {
|
func (a *Mpint) Mul(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mpmulfixfix")
|
yyerror("ovf in mpmulfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -112,14 +112,14 @@ func (a *Mpint) Mul(b *Mpint) {
|
|||||||
a.Val.Mul(&a.Val, &b.Val)
|
a.Val.Mul(&a.Val, &b.Val)
|
||||||
|
|
||||||
if a.checkOverflow(0) {
|
if a.checkOverflow(0) {
|
||||||
Yyerror("constant multiplication overflow")
|
yyerror("constant multiplication overflow")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Mpint) Quo(b *Mpint) {
|
func (a *Mpint) Quo(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mpdivfixfix")
|
yyerror("ovf in mpdivfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -129,14 +129,14 @@ func (a *Mpint) Quo(b *Mpint) {
|
|||||||
|
|
||||||
if a.checkOverflow(0) {
|
if a.checkOverflow(0) {
|
||||||
// can only happen for div-0 which should be checked elsewhere
|
// can only happen for div-0 which should be checked elsewhere
|
||||||
Yyerror("constant division overflow")
|
yyerror("constant division overflow")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Mpint) Rem(b *Mpint) {
|
func (a *Mpint) Rem(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mpmodfixfix")
|
yyerror("ovf in mpmodfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -146,14 +146,14 @@ func (a *Mpint) Rem(b *Mpint) {
|
|||||||
|
|
||||||
if a.checkOverflow(0) {
|
if a.checkOverflow(0) {
|
||||||
// should never happen
|
// should never happen
|
||||||
Yyerror("constant modulo overflow")
|
yyerror("constant modulo overflow")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *Mpint) Or(b *Mpint) {
|
func (a *Mpint) Or(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mporfixfix")
|
yyerror("ovf in mporfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -165,7 +165,7 @@ func (a *Mpint) Or(b *Mpint) {
|
|||||||
func (a *Mpint) And(b *Mpint) {
|
func (a *Mpint) And(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mpandfixfix")
|
yyerror("ovf in mpandfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -177,7 +177,7 @@ func (a *Mpint) And(b *Mpint) {
|
|||||||
func (a *Mpint) AndNot(b *Mpint) {
|
func (a *Mpint) AndNot(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mpandnotfixfix")
|
yyerror("ovf in mpandnotfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -189,7 +189,7 @@ func (a *Mpint) AndNot(b *Mpint) {
|
|||||||
func (a *Mpint) Xor(b *Mpint) {
|
func (a *Mpint) Xor(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mpxorfixfix")
|
yyerror("ovf in mpxorfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -201,7 +201,7 @@ func (a *Mpint) Xor(b *Mpint) {
|
|||||||
func (a *Mpint) Lsh(b *Mpint) {
|
func (a *Mpint) Lsh(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mplshfixfix")
|
yyerror("ovf in mplshfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -213,13 +213,13 @@ func (a *Mpint) Lsh(b *Mpint) {
|
|||||||
if s < 0 {
|
if s < 0 {
|
||||||
msg = "invalid negative shift count"
|
msg = "invalid negative shift count"
|
||||||
}
|
}
|
||||||
Yyerror("%s: %d", msg, s)
|
yyerror("%s: %d", msg, s)
|
||||||
a.SetInt64(0)
|
a.SetInt64(0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.checkOverflow(int(s)) {
|
if a.checkOverflow(int(s)) {
|
||||||
Yyerror("constant shift overflow")
|
yyerror("constant shift overflow")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
a.Val.Lsh(&a.Val, uint(s))
|
a.Val.Lsh(&a.Val, uint(s))
|
||||||
@ -228,7 +228,7 @@ func (a *Mpint) Lsh(b *Mpint) {
|
|||||||
func (a *Mpint) Rsh(b *Mpint) {
|
func (a *Mpint) Rsh(b *Mpint) {
|
||||||
if a.Ovf || b.Ovf {
|
if a.Ovf || b.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("ovf in mprshfixfix")
|
yyerror("ovf in mprshfixfix")
|
||||||
}
|
}
|
||||||
a.SetOverflow()
|
a.SetOverflow()
|
||||||
return
|
return
|
||||||
@ -236,7 +236,7 @@ func (a *Mpint) Rsh(b *Mpint) {
|
|||||||
|
|
||||||
s := b.Int64()
|
s := b.Int64()
|
||||||
if s < 0 {
|
if s < 0 {
|
||||||
Yyerror("invalid negative shift count: %d", s)
|
yyerror("invalid negative shift count: %d", s)
|
||||||
if a.Val.Sign() < 0 {
|
if a.Val.Sign() < 0 {
|
||||||
a.SetInt64(-1)
|
a.SetInt64(-1)
|
||||||
} else {
|
} else {
|
||||||
@ -266,7 +266,7 @@ func (a *Mpint) Neg() {
|
|||||||
func (a *Mpint) Int64() int64 {
|
func (a *Mpint) Int64() int64 {
|
||||||
if a.Ovf {
|
if a.Ovf {
|
||||||
if nsavederrors+nerrors == 0 {
|
if nsavederrors+nerrors == 0 {
|
||||||
Yyerror("constant overflow")
|
yyerror("constant overflow")
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -288,12 +288,12 @@ func (a *Mpint) SetString(as string) {
|
|||||||
// - malformed octal constant
|
// - malformed octal constant
|
||||||
// - malformed decimal constant
|
// - malformed decimal constant
|
||||||
// TODO(gri) use different conversion function
|
// TODO(gri) use different conversion function
|
||||||
Yyerror("malformed integer constant: %s", as)
|
yyerror("malformed integer constant: %s", as)
|
||||||
a.Val.SetUint64(0)
|
a.Val.SetUint64(0)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if a.checkOverflow(0) {
|
if a.checkOverflow(0) {
|
||||||
Yyerror("constant too large: %s", as)
|
yyerror("constant too large: %s", as)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ func (p *noder) importDecl(imp *syntax.ImportDecl) {
|
|||||||
if imp.LocalPkgName != nil {
|
if imp.LocalPkgName != nil {
|
||||||
my = p.name(imp.LocalPkgName)
|
my = p.name(imp.LocalPkgName)
|
||||||
} else {
|
} else {
|
||||||
my = Lookup(ipkg.Name)
|
my = lookup(ipkg.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pack := p.nod(imp, OPACK, nil, nil)
|
pack := p.nod(imp, OPACK, nil, nil)
|
||||||
@ -222,7 +222,7 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
|
|||||||
f.Nbody.Set(body)
|
f.Nbody.Set(body)
|
||||||
f.Noescape = pragma&Noescape != 0
|
f.Noescape = 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
|
||||||
lineno = p.baseline + int32(fun.EndLine) - 1
|
lineno = p.baseline + int32(fun.EndLine) - 1
|
||||||
@ -243,13 +243,13 @@ func (p *noder) funcHeader(fun *syntax.FuncDecl) *Node {
|
|||||||
if name.Name == "init" {
|
if name.Name == "init" {
|
||||||
name = renameinit()
|
name = renameinit()
|
||||||
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
||||||
Yyerror("func init must have no arguments and no return values")
|
yyerror("func init must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if localpkg.Name == "main" && name.Name == "main" {
|
if localpkg.Name == "main" && name.Name == "main" {
|
||||||
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
||||||
Yyerror("func main must have no arguments and no return values")
|
yyerror("func main must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,9 +300,9 @@ func (p *noder) param(param *syntax.Field, dddOk, final bool) *Node {
|
|||||||
// rewrite ...T parameter
|
// rewrite ...T parameter
|
||||||
if typ.Op == ODDD {
|
if typ.Op == ODDD {
|
||||||
if !dddOk {
|
if !dddOk {
|
||||||
Yyerror("cannot use ... in receiver or result parameter list")
|
yyerror("cannot use ... in receiver or result parameter list")
|
||||||
} else if !final {
|
} else if !final {
|
||||||
Yyerror("can only use ... with final parameter in list")
|
yyerror("can only use ... with final parameter in list")
|
||||||
}
|
}
|
||||||
typ.Op = OTARRAY
|
typ.Op = OTARRAY
|
||||||
typ.Right = typ.Left
|
typ.Right = typ.Left
|
||||||
@ -371,7 +371,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
|
|||||||
obj.Used = true
|
obj.Used = true
|
||||||
return oldname(s)
|
return oldname(s)
|
||||||
}
|
}
|
||||||
return p.setlineno(expr, NodSym(OXDOT, obj, sel))
|
return p.setlineno(expr, nodSym(OXDOT, obj, sel))
|
||||||
case *syntax.IndexExpr:
|
case *syntax.IndexExpr:
|
||||||
return p.nod(expr, OINDEX, p.expr(expr.X), p.expr(expr.Index))
|
return p.nod(expr, OINDEX, p.expr(expr.X), p.expr(expr.Index))
|
||||||
case *syntax.SliceExpr:
|
case *syntax.SliceExpr:
|
||||||
@ -449,7 +449,7 @@ func (p *noder) expr(expr syntax.Expr) *Node {
|
|||||||
if expr.Lhs != nil {
|
if expr.Lhs != nil {
|
||||||
n.Left = p.declName(expr.Lhs)
|
n.Left = p.declName(expr.Lhs)
|
||||||
if isblank(n.Left) {
|
if isblank(n.Left) {
|
||||||
Yyerror("invalid variable name %v in type switch", n.Left)
|
yyerror("invalid variable name %v in type switch", n.Left)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
@ -530,7 +530,7 @@ func (p *noder) packname(expr syntax.Expr) *Sym {
|
|||||||
s := p.name(expr.Sel)
|
s := p.name(expr.Sel)
|
||||||
var pkg *Pkg
|
var pkg *Pkg
|
||||||
if name.Def == nil || name.Def.Op != OPACK {
|
if name.Def == nil || name.Def.Op != OPACK {
|
||||||
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.Used = true
|
||||||
@ -666,7 +666,7 @@ func (p *noder) stmt(stmt syntax.Stmt) *Node {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if ln.Sym.Def != ln {
|
if ln.Sym.Def != ln {
|
||||||
Yyerror("%s is shadowed during return", ln.Sym.Name)
|
yyerror("%s is shadowed during return", ln.Sym.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -948,7 +948,7 @@ func (p *noder) basicLit(lit *syntax.BasicLit) Val {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) name(name *syntax.Name) *Sym {
|
func (p *noder) name(name *syntax.Name) *Sym {
|
||||||
return Lookup(name.Value)
|
return lookup(name.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *noder) mkname(name *syntax.Name) *Node {
|
func (p *noder) mkname(name *syntax.Name) *Node {
|
||||||
@ -1034,7 +1034,7 @@ func (p *noder) pragma(pos, line int, text string) syntax.Pragma {
|
|||||||
p.error(pos, line, "usage: //go:linkname localname linkname")
|
p.error(pos, line, "usage: //go:linkname localname linkname")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
Lookup(f[1]).Linkname = f[2]
|
lookup(f[1]).Linkname = f[2]
|
||||||
|
|
||||||
case strings.HasPrefix(text, "go:cgo_"):
|
case strings.HasPrefix(text, "go:cgo_"):
|
||||||
pragcgobuf += pragcgo(text)
|
pragcgobuf += pragcgo(text)
|
||||||
@ -1044,7 +1044,7 @@ func (p *noder) pragma(pos, line int, text string) syntax.Pragma {
|
|||||||
if i := strings.Index(text, " "); i >= 0 {
|
if i := strings.Index(text, " "); i >= 0 {
|
||||||
verb = verb[:i]
|
verb = verb[:i]
|
||||||
}
|
}
|
||||||
return syntax.Pragma(PragmaValue(verb))
|
return syntax.Pragma(pragmaValue(verb))
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -53,7 +53,7 @@ func dumpobj1(outfile string, mode int) {
|
|||||||
var err error
|
var err error
|
||||||
bout, err = bio.Create(outfile)
|
bout, err = bio.Create(outfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
fmt.Printf("can't create %s: %v\n", outfile, err)
|
fmt.Printf("can't create %s: %v\n", outfile, err)
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
@ -363,7 +363,7 @@ func ordercall(n *Node, order *Order) {
|
|||||||
ordercallargs(&n.List, order)
|
ordercallargs(&n.List, order)
|
||||||
|
|
||||||
if n.Op == OCALLFUNC {
|
if n.Op == OCALLFUNC {
|
||||||
t, it := IterFields(n.Left.Type.Params())
|
t, it := iterFields(n.Left.Type.Params())
|
||||||
for i := range n.List.Slice() {
|
for i := range n.List.Slice() {
|
||||||
// Check for "unsafe-uintptr" tag provided by escape analysis.
|
// Check for "unsafe-uintptr" tag provided by escape analysis.
|
||||||
// If present and the argument is really a pointer being converted
|
// If present and the argument is really a pointer being converted
|
||||||
@ -815,7 +815,7 @@ func orderstmt(n *Node, order *Order) {
|
|||||||
if r != nil {
|
if r != nil {
|
||||||
switch r.Op {
|
switch r.Op {
|
||||||
default:
|
default:
|
||||||
Yyerror("unknown op in select %v", r.Op)
|
yyerror("unknown op in select %v", r.Op)
|
||||||
Dump("select case", r)
|
Dump("select case", r)
|
||||||
|
|
||||||
// If this is case x := <-ch or case x, y := <-ch, the case has
|
// If this is case x := <-ch or case x, y := <-ch, the case has
|
||||||
@ -837,7 +837,7 @@ func orderstmt(n *Node, order *Order) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if r.Ninit.Len() != 0 {
|
if r.Ninit.Len() != 0 {
|
||||||
Yyerror("ninit on select recv")
|
yyerror("ninit on select recv")
|
||||||
dumplist("ninit", r.Ninit)
|
dumplist("ninit", r.Ninit)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -899,7 +899,7 @@ func orderstmt(n *Node, order *Order) {
|
|||||||
|
|
||||||
case OSEND:
|
case OSEND:
|
||||||
if r.Ninit.Len() != 0 {
|
if r.Ninit.Len() != 0 {
|
||||||
Yyerror("ninit on select send")
|
yyerror("ninit on select send")
|
||||||
dumplist("ninit", r.Ninit)
|
dumplist("ninit", r.Ninit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ func (p *parser) syntax_error(msg string) {
|
|||||||
msg = ", " + msg
|
msg = ", " + msg
|
||||||
default:
|
default:
|
||||||
// plain error - we don't care about current token
|
// plain error - we don't care about current token
|
||||||
Yyerror("syntax error: %s", msg)
|
yyerror("syntax error: %s", msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ func (p *parser) syntax_error(msg string) {
|
|||||||
tok = tokstring(p.tok)
|
tok = tokstring(p.tok)
|
||||||
}
|
}
|
||||||
|
|
||||||
Yyerror("syntax error: unexpected %s", tok+msg)
|
yyerror("syntax error: unexpected %s", tok+msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like syntax_error, but reports error at given line rather than current lexer line.
|
// Like syntax_error, but reports error at given line rather than current lexer line.
|
||||||
@ -328,7 +328,7 @@ func (p *parser) importdcl() {
|
|||||||
|
|
||||||
case '.':
|
case '.':
|
||||||
// import into my name space
|
// import into my name space
|
||||||
my = Lookup(".")
|
my = lookup(".")
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +358,7 @@ func (p *parser) importdcl() {
|
|||||||
ipkg.Direct = true
|
ipkg.Direct = true
|
||||||
|
|
||||||
if my == nil {
|
if my == nil {
|
||||||
my = Lookup(ipkg.Name)
|
my = lookup(ipkg.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pack := Nod(OPACK, nil, nil)
|
pack := Nod(OPACK, nil, nil)
|
||||||
@ -372,7 +372,7 @@ func (p *parser) importdcl() {
|
|||||||
}
|
}
|
||||||
if my.Name == "init" {
|
if my.Name == "init" {
|
||||||
lineno = line
|
lineno = line
|
||||||
Yyerror("cannot import package as init - init must be a func")
|
yyerror("cannot import package as init - init must be a func")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if my.Name == "_" {
|
if my.Name == "_" {
|
||||||
@ -607,12 +607,12 @@ func (p *parser) simple_stmt(labelOk, rangeOk bool) *Node {
|
|||||||
if rhs[0].Op == OTYPESW {
|
if rhs[0].Op == OTYPESW {
|
||||||
ts := Nod(OTYPESW, nil, rhs[0].Right)
|
ts := Nod(OTYPESW, nil, rhs[0].Right)
|
||||||
if len(rhs) > 1 {
|
if len(rhs) > 1 {
|
||||||
Yyerror("expr.(type) must be alone in list")
|
yyerror("expr.(type) must be alone in list")
|
||||||
}
|
}
|
||||||
if len(lhs) > 1 {
|
if len(lhs) > 1 {
|
||||||
Yyerror("argument count mismatch: %d = %d", len(lhs), 1)
|
yyerror("argument count mismatch: %d = %d", len(lhs), 1)
|
||||||
} else if (lhs[0].Op != ONAME && lhs[0].Op != OTYPE && lhs[0].Op != ONONAME && (lhs[0].Op != OLITERAL || lhs[0].Name == nil)) || isblank(lhs[0]) {
|
} else if (lhs[0].Op != ONAME && lhs[0].Op != OTYPE && lhs[0].Op != ONONAME && (lhs[0].Op != OLITERAL || lhs[0].Name == nil)) || isblank(lhs[0]) {
|
||||||
Yyerror("invalid variable name %v in type switch", lhs[0])
|
yyerror("invalid variable name %v in type switch", lhs[0])
|
||||||
} else {
|
} else {
|
||||||
ts.Left = dclname(lhs[0].Sym)
|
ts.Left = dclname(lhs[0].Sym)
|
||||||
} // it's a colas, so must not re-use an oldname
|
} // it's a colas, so must not re-use an oldname
|
||||||
@ -866,7 +866,7 @@ func (p *parser) for_header() *Node {
|
|||||||
if init != nil || post != nil {
|
if init != nil || post != nil {
|
||||||
// init ; test ; incr
|
// init ; test ; incr
|
||||||
if post != nil && post.Colas {
|
if post != nil && post.Colas {
|
||||||
Yyerror("cannot declare in the for-increment")
|
yyerror("cannot declare in the for-increment")
|
||||||
}
|
}
|
||||||
h := Nod(OFOR, nil, nil)
|
h := Nod(OFOR, nil, nil)
|
||||||
if init != nil {
|
if init != nil {
|
||||||
@ -932,7 +932,7 @@ func (p *parser) header(for_stmt bool) (init, cond, post *Node) {
|
|||||||
// accept potential vardcl but complain
|
// accept potential vardcl but complain
|
||||||
// (for test/syntax/forvar.go)
|
// (for test/syntax/forvar.go)
|
||||||
if for_stmt && p.tok == LVAR {
|
if for_stmt && p.tok == LVAR {
|
||||||
Yyerror("var declaration not allowed in for initializer")
|
yyerror("var declaration not allowed in for initializer")
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
init = p.simple_stmt(false, for_stmt)
|
init = p.simple_stmt(false, for_stmt)
|
||||||
@ -992,7 +992,7 @@ func (p *parser) if_stmt() *Node {
|
|||||||
|
|
||||||
stmt := p.if_header()
|
stmt := p.if_header()
|
||||||
if stmt.Left == nil {
|
if stmt.Left == nil {
|
||||||
Yyerror("missing condition in if statement")
|
yyerror("missing condition in if statement")
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt.Nbody.Set(p.loop_body("if clause"))
|
stmt.Nbody.Set(p.loop_body("if clause"))
|
||||||
@ -1192,10 +1192,10 @@ func (p *parser) pseudocall() *Node {
|
|||||||
case OCALL:
|
case OCALL:
|
||||||
return x
|
return x
|
||||||
case OPAREN:
|
case OPAREN:
|
||||||
Yyerror("expression in go/defer must not be parenthesized")
|
yyerror("expression in go/defer must not be parenthesized")
|
||||||
// already progressed, no need to advance
|
// already progressed, no need to advance
|
||||||
default:
|
default:
|
||||||
Yyerror("expression in go/defer must be function call")
|
yyerror("expression in go/defer must be function call")
|
||||||
// already progressed, no need to advance
|
// already progressed, no need to advance
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -1365,7 +1365,7 @@ loop:
|
|||||||
case 0:
|
case 0:
|
||||||
i := index[0]
|
i := index[0]
|
||||||
if i == nil {
|
if i == nil {
|
||||||
Yyerror("missing index in index expression")
|
yyerror("missing index in index expression")
|
||||||
}
|
}
|
||||||
x = Nod(OINDEX, x, i)
|
x = Nod(OINDEX, x, i)
|
||||||
case 1:
|
case 1:
|
||||||
@ -1373,10 +1373,10 @@ loop:
|
|||||||
x.SetSliceBounds(index[0], index[1], nil)
|
x.SetSliceBounds(index[0], index[1], nil)
|
||||||
case 2:
|
case 2:
|
||||||
if index[1] == nil {
|
if index[1] == nil {
|
||||||
Yyerror("middle index required in 3-index slice")
|
yyerror("middle index required in 3-index slice")
|
||||||
}
|
}
|
||||||
if index[2] == nil {
|
if index[2] == nil {
|
||||||
Yyerror("final index required in 3-index slice")
|
yyerror("final index required in 3-index slice")
|
||||||
}
|
}
|
||||||
x = Nod(OSLICE3, x, nil)
|
x = Nod(OSLICE3, x, nil)
|
||||||
x.SetSliceBounds(index[0], index[1], index[2])
|
x.SetSliceBounds(index[0], index[1], index[2])
|
||||||
@ -1581,7 +1581,7 @@ func (p *parser) dotdotdot() *Node {
|
|||||||
return Nod(ODDD, typ, nil)
|
return Nod(ODDD, typ, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
Yyerror("final argument in variadic function missing type")
|
yyerror("final argument in variadic function missing type")
|
||||||
return Nod(ODDD, typenod(typ(TINTER)), nil)
|
return Nod(ODDD, typenod(typ(TINTER)), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1737,7 +1737,7 @@ func (p *parser) new_dotname(obj *Node) *Node {
|
|||||||
obj.Used = true
|
obj.Used = true
|
||||||
return oldname(s)
|
return oldname(s)
|
||||||
}
|
}
|
||||||
return NodSym(OXDOT, obj, sel)
|
return nodSym(OXDOT, obj, sel)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *parser) dotname() *Node {
|
func (p *parser) dotname() *Node {
|
||||||
@ -1815,7 +1815,7 @@ func (p *parser) xfndcl() *Node {
|
|||||||
f.Nbody.Set(body)
|
f.Nbody.Set(body)
|
||||||
f.Noescape = p.pragma&Noescape != 0
|
f.Noescape = p.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 = p.pragma
|
f.Func.Pragma = p.pragma
|
||||||
f.Func.Endlineno = lineno
|
f.Func.Endlineno = lineno
|
||||||
@ -1844,13 +1844,13 @@ func (p *parser) fndcl() *Node {
|
|||||||
if name.Name == "init" {
|
if name.Name == "init" {
|
||||||
name = renameinit()
|
name = renameinit()
|
||||||
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
||||||
Yyerror("func init must have no arguments and no return values")
|
yyerror("func init must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if localpkg.Name == "main" && name.Name == "main" {
|
if localpkg.Name == "main" && name.Name == "main" {
|
||||||
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
if t.List.Len() > 0 || t.Rlist.Len() > 0 {
|
||||||
Yyerror("func main must have no arguments and no return values")
|
yyerror("func main must have no arguments and no return values")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1875,17 +1875,17 @@ func (p *parser) fndcl() *Node {
|
|||||||
|
|
||||||
// check after parsing header for fault-tolerance
|
// check after parsing header for fault-tolerance
|
||||||
if recv == nil {
|
if recv == nil {
|
||||||
Yyerror("method has no receiver")
|
yyerror("method has no receiver")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(rparam) > 1 {
|
if len(rparam) > 1 {
|
||||||
Yyerror("method has multiple receivers")
|
yyerror("method has multiple receivers")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if recv.Op != ODCLFIELD {
|
if recv.Op != ODCLFIELD {
|
||||||
Yyerror("bad receiver in method")
|
yyerror("bad receiver in method")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2026,7 +2026,7 @@ func (p *parser) structdcl() []*Node {
|
|||||||
|
|
||||||
field.Right = Nod(OIND, field.Right, nil)
|
field.Right = Nod(OIND, field.Right, nil)
|
||||||
field.SetVal(tag)
|
field.SetVal(tag)
|
||||||
Yyerror("cannot parenthesize embedded type")
|
yyerror("cannot parenthesize embedded type")
|
||||||
return []*Node{field}
|
return []*Node{field}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -2036,7 +2036,7 @@ func (p *parser) structdcl() []*Node {
|
|||||||
tag := p.oliteral()
|
tag := p.oliteral()
|
||||||
|
|
||||||
field.SetVal(tag)
|
field.SetVal(tag)
|
||||||
Yyerror("cannot parenthesize embedded type")
|
yyerror("cannot parenthesize embedded type")
|
||||||
return []*Node{field}
|
return []*Node{field}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2050,7 +2050,7 @@ func (p *parser) structdcl() []*Node {
|
|||||||
|
|
||||||
field.Right = Nod(OIND, field.Right, nil)
|
field.Right = Nod(OIND, field.Right, nil)
|
||||||
field.SetVal(tag)
|
field.SetVal(tag)
|
||||||
Yyerror("cannot parenthesize embedded type")
|
yyerror("cannot parenthesize embedded type")
|
||||||
return []*Node{field}
|
return []*Node{field}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -2100,7 +2100,7 @@ func (p *parser) packname(name *Sym) *Sym {
|
|||||||
|
|
||||||
var pkg *Pkg
|
var pkg *Pkg
|
||||||
if name.Def == nil || name.Def.Op != OPACK {
|
if name.Def == nil || name.Def.Op != OPACK {
|
||||||
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.Used = true
|
||||||
@ -2168,7 +2168,7 @@ func (p *parser) interfacedcl() *Node {
|
|||||||
pname := p.packname(nil)
|
pname := p.packname(nil)
|
||||||
p.want(')')
|
p.want(')')
|
||||||
n := Nod(ODCLFIELD, nil, oldname(pname))
|
n := Nod(ODCLFIELD, nil, oldname(pname))
|
||||||
Yyerror("cannot parenthesize embedded type")
|
yyerror("cannot parenthesize embedded type")
|
||||||
return n
|
return n
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2287,7 +2287,7 @@ func (p *parser) param_list(dddOk bool) []*Node {
|
|||||||
p.typ = T
|
p.typ = T
|
||||||
}
|
}
|
||||||
if T == nil {
|
if T == nil {
|
||||||
Yyerror("mixed named and unnamed function parameters")
|
yyerror("mixed named and unnamed function parameters")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2314,9 +2314,9 @@ func (p *parser) param_list(dddOk bool) []*Node {
|
|||||||
// rewrite ...T parameter
|
// rewrite ...T parameter
|
||||||
if typ != nil && typ.Op == ODDD {
|
if typ != nil && typ.Op == ODDD {
|
||||||
if !dddOk {
|
if !dddOk {
|
||||||
Yyerror("cannot use ... in receiver or result parameter list")
|
yyerror("cannot use ... in receiver or result parameter list")
|
||||||
} else if i+1 < len(params) {
|
} else if i+1 < len(params) {
|
||||||
Yyerror("can only use ... with final parameter in list")
|
yyerror("can only use ... with final parameter in list")
|
||||||
}
|
}
|
||||||
typ.Op = OTARRAY
|
typ.Op = OTARRAY
|
||||||
typ.Right = typ.Left
|
typ.Right = typ.Left
|
||||||
@ -2418,7 +2418,7 @@ func (p *parser) stmt() *Node {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if ln.Sym.Def != ln {
|
if ln.Sym.Def != ln {
|
||||||
Yyerror("%s is shadowed during return", ln.Sym.Name)
|
yyerror("%s is shadowed during return", ln.Sym.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ var makefuncdatasym_nsym int
|
|||||||
func makefuncdatasym(nameprefix string, funcdatakind int64) *Sym {
|
func makefuncdatasym(nameprefix string, funcdatakind int64) *Sym {
|
||||||
var nod Node
|
var nod Node
|
||||||
|
|
||||||
sym := LookupN(nameprefix, makefuncdatasym_nsym)
|
sym := lookupN(nameprefix, makefuncdatasym_nsym)
|
||||||
makefuncdatasym_nsym++
|
makefuncdatasym_nsym++
|
||||||
pnod := newname(sym)
|
pnod := newname(sym)
|
||||||
pnod.Class = PEXTERN
|
pnod.Class = PEXTERN
|
||||||
@ -89,7 +89,7 @@ func gvardefx(n *Node, as obj.As) {
|
|||||||
Fatalf("gvardef nil")
|
Fatalf("gvardef nil")
|
||||||
}
|
}
|
||||||
if n.Op != ONAME {
|
if n.Op != ONAME {
|
||||||
Yyerror("gvardef %#v; %v", n.Op, n)
|
yyerror("gvardef %#v; %v", n.Op, n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ func emitptrargsmap() {
|
|||||||
if Curfn.Func.Nname.Sym.Name == "_" {
|
if Curfn.Func.Nname.Sym.Name == "_" {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sym := Lookup(fmt.Sprintf("%s.args_stackmap", Curfn.Func.Nname.Sym.Name))
|
sym := lookup(fmt.Sprintf("%s.args_stackmap", Curfn.Func.Nname.Sym.Name))
|
||||||
|
|
||||||
nptr := int(Curfn.Type.ArgWidth() / int64(Widthptr))
|
nptr := int(Curfn.Type.ArgWidth() / int64(Widthptr))
|
||||||
bv := bvalloc(int32(nptr) * 2)
|
bv := bvalloc(int32(nptr) * 2)
|
||||||
@ -281,7 +281,7 @@ func allocauto(ptxt *obj.Prog) {
|
|||||||
}
|
}
|
||||||
if Stksize >= 1<<31 {
|
if Stksize >= 1<<31 {
|
||||||
setlineno(Curfn)
|
setlineno(Curfn)
|
||||||
Yyerror("stack frame too large (>2GB)")
|
yyerror("stack frame too large (>2GB)")
|
||||||
}
|
}
|
||||||
|
|
||||||
stkdelta[n] = -Stksize - n.Xoffset
|
stkdelta[n] = -Stksize - n.Xoffset
|
||||||
@ -325,7 +325,7 @@ func compile(fn *Node) {
|
|||||||
|
|
||||||
if fn.Nbody.Len() == 0 {
|
if fn.Nbody.Len() == 0 {
|
||||||
if pure_go || strings.HasPrefix(fn.Func.Nname.Sym.Name, "init.") {
|
if pure_go || strings.HasPrefix(fn.Func.Nname.Sym.Name, "init.") {
|
||||||
Yyerror("missing function body for %q", fn.Func.Nname.Sym.Name)
|
yyerror("missing function body for %q", fn.Func.Nname.Sym.Name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -806,7 +806,7 @@ func checkauto(fn *Node, p *obj.Prog, n *Node) {
|
|||||||
for _, ln := range fn.Func.Dcl {
|
for _, ln := range fn.Func.Dcl {
|
||||||
fmt.Printf("\t%v (%p; class=%d)\n", ln, ln, ln.Class)
|
fmt.Printf("\t%v (%p; class=%d)\n", ln, ln, ln.Class)
|
||||||
}
|
}
|
||||||
Yyerror("checkauto: invariant lost")
|
yyerror("checkauto: invariant lost")
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkparam(fn *Node, p *obj.Prog, n *Node) {
|
func checkparam(fn *Node, p *obj.Prog, n *Node) {
|
||||||
@ -823,7 +823,7 @@ func checkparam(fn *Node, p *obj.Prog, n *Node) {
|
|||||||
for _, ln := range fn.Func.Dcl {
|
for _, ln := range fn.Func.Dcl {
|
||||||
fmt.Printf("\t%v (%p; class=%d)\n", ln, ln, ln.Class)
|
fmt.Printf("\t%v (%p; class=%d)\n", ln, ln, ln.Class)
|
||||||
}
|
}
|
||||||
Yyerror("checkparam: invariant lost")
|
yyerror("checkparam: invariant lost")
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkprog(fn *Node, p *obj.Prog) {
|
func checkprog(fn *Node, p *obj.Prog) {
|
||||||
@ -1423,7 +1423,7 @@ func livenessepilogue(lv *Liveness) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FNV-1 hash function constants.
|
// FNV-1 hash function constants.
|
||||||
|
@ -230,7 +230,7 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
|
|||||||
instrumentnode(&n.Left, init, 0, 0)
|
instrumentnode(&n.Left, init, 0, 0)
|
||||||
if n.Left.Type.IsMap() {
|
if n.Left.Type.IsMap() {
|
||||||
n1 := Nod(OCONVNOP, n.Left, nil)
|
n1 := Nod(OCONVNOP, n.Left, nil)
|
||||||
n1.Type = Ptrto(Types[TUINT8])
|
n1.Type = ptrto(Types[TUINT8])
|
||||||
n1 = Nod(OIND, n1, nil)
|
n1 = Nod(OIND, n1, nil)
|
||||||
n1 = typecheck(n1, Erv)
|
n1 = typecheck(n1, Erv)
|
||||||
callinstr(&n1, init, 0, skip)
|
callinstr(&n1, init, 0, skip)
|
||||||
@ -375,17 +375,17 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
|
|||||||
OAS2RECV,
|
OAS2RECV,
|
||||||
OAS2MAPR,
|
OAS2MAPR,
|
||||||
OASOP:
|
OASOP:
|
||||||
Yyerror("instrument: %v must be lowered by now", n.Op)
|
yyerror("instrument: %v must be lowered by now", n.Op)
|
||||||
|
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
// impossible nodes: only appear in backend.
|
// impossible nodes: only appear in backend.
|
||||||
case ORROTC, OEXTEND:
|
case ORROTC, OEXTEND:
|
||||||
Yyerror("instrument: %v cannot exist now", n.Op)
|
yyerror("instrument: %v cannot exist now", n.Op)
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
case OGETG:
|
case OGETG:
|
||||||
Yyerror("instrument: OGETG can happen only in runtime which we don't instrument")
|
yyerror("instrument: OGETG can happen only in runtime which we don't instrument")
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
case OFOR:
|
case OFOR:
|
||||||
@ -587,7 +587,7 @@ func uintptraddr(n *Node) *Node {
|
|||||||
|
|
||||||
func detachexpr(n *Node, init *Nodes) *Node {
|
func detachexpr(n *Node, init *Nodes) *Node {
|
||||||
addr := Nod(OADDR, n, nil)
|
addr := Nod(OADDR, n, nil)
|
||||||
l := temp(Ptrto(n.Type))
|
l := temp(ptrto(n.Type))
|
||||||
as := Nod(OAS, l, addr)
|
as := Nod(OAS, l, addr)
|
||||||
as = typecheck(as, Etop)
|
as = typecheck(as, Etop)
|
||||||
as = walkexpr(as, init)
|
as = walkexpr(as, init)
|
||||||
|
@ -48,7 +48,7 @@ func typecheckrange(n *Node) {
|
|||||||
toomany = 0
|
toomany = 0
|
||||||
switch t.Etype {
|
switch t.Etype {
|
||||||
default:
|
default:
|
||||||
Yyerror("cannot range over %L", n.Right)
|
yyerror("cannot range over %L", n.Right)
|
||||||
goto out
|
goto out
|
||||||
|
|
||||||
case TARRAY, TSLICE:
|
case TARRAY, TSLICE:
|
||||||
@ -61,7 +61,7 @@ func typecheckrange(n *Node) {
|
|||||||
|
|
||||||
case TCHAN:
|
case TCHAN:
|
||||||
if !t.ChanDir().CanRecv() {
|
if !t.ChanDir().CanRecv() {
|
||||||
Yyerror("invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
|
yyerror("invalid operation: range %v (receive from send-only type %v)", n.Right, n.Right.Type)
|
||||||
goto out
|
goto out
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ func typecheckrange(n *Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n.List.Len() > 2 || toomany != 0 {
|
if n.List.Len() > 2 || toomany != 0 {
|
||||||
Yyerror("too many variables in range")
|
yyerror("too many variables in range")
|
||||||
}
|
}
|
||||||
|
|
||||||
v1 = nil
|
v1 = nil
|
||||||
@ -104,7 +104,7 @@ func typecheckrange(n *Node) {
|
|||||||
if v1.Name != nil && v1.Name.Defn == n {
|
if v1.Name != nil && v1.Name.Defn == n {
|
||||||
v1.Type = t1
|
v1.Type = t1
|
||||||
} else if v1.Type != nil && assignop(t1, v1.Type, &why) == 0 {
|
} else if v1.Type != nil && assignop(t1, v1.Type, &why) == 0 {
|
||||||
Yyerror("cannot assign type %v to %L in range%s", t1, v1, why)
|
yyerror("cannot assign type %v to %L in range%s", t1, v1, why)
|
||||||
}
|
}
|
||||||
checkassign(n, v1)
|
checkassign(n, v1)
|
||||||
}
|
}
|
||||||
@ -113,7 +113,7 @@ func typecheckrange(n *Node) {
|
|||||||
if v2.Name != nil && v2.Name.Defn == n {
|
if v2.Name != nil && v2.Name.Defn == n {
|
||||||
v2.Type = t2
|
v2.Type = t2
|
||||||
} else if v2.Type != nil && assignop(t2, v2.Type, &why) == 0 {
|
} else if v2.Type != nil && assignop(t2, v2.Type, &why) == 0 {
|
||||||
Yyerror("cannot assign type %v to %L in range%s", t2, v2, why)
|
yyerror("cannot assign type %v to %L in range%s", t2, v2, why)
|
||||||
}
|
}
|
||||||
checkassign(n, v2)
|
checkassign(n, v2)
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ func walkrange(n *Node) {
|
|||||||
init = append(init, Nod(OAS, hv1, nil))
|
init = append(init, Nod(OAS, hv1, nil))
|
||||||
init = append(init, Nod(OAS, hn, Nod(OLEN, ha, nil)))
|
init = append(init, Nod(OAS, hn, Nod(OLEN, ha, nil)))
|
||||||
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.Bounded = true
|
||||||
init = append(init, Nod(OAS, hp, Nod(OADDR, tmp, nil)))
|
init = append(init, Nod(OAS, hp, Nod(OADDR, tmp, nil)))
|
||||||
@ -235,20 +235,20 @@ func walkrange(n *Node) {
|
|||||||
|
|
||||||
fn = substArgTypes(fn, t.Key(), t.Val(), th)
|
fn = substArgTypes(fn, t.Key(), t.Val(), th)
|
||||||
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil)))
|
init = append(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil)))
|
||||||
n.Left = Nod(ONE, NodSym(ODOT, hit, keysym), nodnil())
|
n.Left = Nod(ONE, nodSym(ODOT, hit, keysym), nodnil())
|
||||||
|
|
||||||
fn = syslook("mapiternext")
|
fn = syslook("mapiternext")
|
||||||
fn = substArgTypes(fn, th)
|
fn = substArgTypes(fn, th)
|
||||||
n.Right = mkcall1(fn, nil, nil, Nod(OADDR, hit, nil))
|
n.Right = mkcall1(fn, nil, nil, Nod(OADDR, hit, nil))
|
||||||
|
|
||||||
key := NodSym(ODOT, hit, keysym)
|
key := nodSym(ODOT, hit, keysym)
|
||||||
key = Nod(OIND, key, nil)
|
key = Nod(OIND, key, nil)
|
||||||
if v1 == nil {
|
if v1 == nil {
|
||||||
body = nil
|
body = nil
|
||||||
} else if v2 == nil {
|
} else if v2 == nil {
|
||||||
body = []*Node{Nod(OAS, v1, key)}
|
body = []*Node{Nod(OAS, v1, key)}
|
||||||
} else {
|
} else {
|
||||||
val := NodSym(ODOT, hit, valsym)
|
val := nodSym(ODOT, hit, valsym)
|
||||||
val = Nod(OIND, val, nil)
|
val = Nod(OIND, val, nil)
|
||||||
a := Nod(OAS2, nil, nil)
|
a := Nod(OAS2, nil, nil)
|
||||||
a.List.Set([]*Node{v1, v2})
|
a.List.Set([]*Node{v1, v2})
|
||||||
@ -269,7 +269,7 @@ func walkrange(n *Node) {
|
|||||||
}
|
}
|
||||||
hb := temp(Types[TBOOL])
|
hb := temp(Types[TBOOL])
|
||||||
|
|
||||||
n.Left = Nod(ONE, hb, Nodbool(false))
|
n.Left = Nod(ONE, hb, nodbool(false))
|
||||||
a := Nod(OAS2RECV, nil, nil)
|
a := Nod(OAS2RECV, nil, nil)
|
||||||
a.Typecheck = 1
|
a.Typecheck = 1
|
||||||
a.List.Set([]*Node{hv1, hb})
|
a.List.Set([]*Node{hv1, hb})
|
||||||
@ -406,13 +406,13 @@ func memclrrange(n, v1, v2, a *Node) bool {
|
|||||||
n.Left = Nod(ONE, Nod(OLEN, a, nil), nodintconst(0))
|
n.Left = Nod(ONE, Nod(OLEN, a, nil), nodintconst(0))
|
||||||
|
|
||||||
// hp = &a[0]
|
// hp = &a[0]
|
||||||
hp := temp(Ptrto(Types[TUINT8]))
|
hp := temp(ptrto(Types[TUINT8]))
|
||||||
|
|
||||||
tmp := Nod(OINDEX, a, nodintconst(0))
|
tmp := Nod(OINDEX, a, nodintconst(0))
|
||||||
tmp.Bounded = true
|
tmp.Bounded = true
|
||||||
tmp = Nod(OADDR, tmp, nil)
|
tmp = Nod(OADDR, tmp, nil)
|
||||||
tmp = Nod(OCONVNOP, tmp, nil)
|
tmp = Nod(OCONVNOP, tmp, nil)
|
||||||
tmp.Type = Ptrto(Types[TUINT8])
|
tmp.Type = ptrto(Types[TUINT8])
|
||||||
n.Nbody.Append(Nod(OAS, hp, tmp))
|
n.Nbody.Append(Nod(OAS, hp, tmp))
|
||||||
|
|
||||||
// hn = len(a) * sizeof(elem(a))
|
// hn = len(a) * sizeof(elem(a))
|
||||||
|
@ -102,10 +102,10 @@ func mapbucket(t *Type) *Type {
|
|||||||
dowidth(keytype)
|
dowidth(keytype)
|
||||||
dowidth(valtype)
|
dowidth(valtype)
|
||||||
if keytype.Width > MAXKEYSIZE {
|
if keytype.Width > MAXKEYSIZE {
|
||||||
keytype = Ptrto(keytype)
|
keytype = ptrto(keytype)
|
||||||
}
|
}
|
||||||
if valtype.Width > MAXVALSIZE {
|
if valtype.Width > MAXVALSIZE {
|
||||||
valtype = Ptrto(valtype)
|
valtype = ptrto(valtype)
|
||||||
}
|
}
|
||||||
|
|
||||||
field := make([]*Field, 0, 5)
|
field := make([]*Field, 0, 5)
|
||||||
@ -149,7 +149,7 @@ func mapbucket(t *Type) *Type {
|
|||||||
// Arrange for the bucket to have no pointers by changing
|
// Arrange for the bucket to have no pointers by changing
|
||||||
// the type of the overflow field to uintptr in this case.
|
// the type of the overflow field to uintptr in this case.
|
||||||
// See comment on hmap.overflow in ../../../../runtime/hashmap.go.
|
// See comment on hmap.overflow in ../../../../runtime/hashmap.go.
|
||||||
otyp := Ptrto(bucket)
|
otyp := ptrto(bucket)
|
||||||
if !haspointers(t.Val()) && !haspointers(t.Key()) && t.Val().Width <= MAXVALSIZE && t.Key().Width <= MAXKEYSIZE {
|
if !haspointers(t.Val()) && !haspointers(t.Key()) && t.Val().Width <= MAXVALSIZE && t.Key().Width <= MAXKEYSIZE {
|
||||||
otyp = Types[TUINTPTR]
|
otyp = Types[TUINTPTR]
|
||||||
}
|
}
|
||||||
@ -165,7 +165,7 @@ func mapbucket(t *Type) *Type {
|
|||||||
// Double-check that overflow field is final memory in struct,
|
// Double-check that overflow field is final memory in struct,
|
||||||
// with no padding at end. See comment above.
|
// with no padding at end. See comment above.
|
||||||
if ovf.Offset != bucket.Width-int64(Widthptr) {
|
if ovf.Offset != bucket.Width-int64(Widthptr) {
|
||||||
Yyerror("bad math in mapbucket for %v", t)
|
yyerror("bad math in mapbucket for %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.MapType().Bucket = bucket
|
t.MapType().Bucket = bucket
|
||||||
@ -188,8 +188,8 @@ func hmap(t *Type) *Type {
|
|||||||
makefield("B", Types[TUINT8]),
|
makefield("B", Types[TUINT8]),
|
||||||
makefield("noverflow", Types[TUINT16]),
|
makefield("noverflow", Types[TUINT16]),
|
||||||
makefield("hash0", Types[TUINT32]),
|
makefield("hash0", Types[TUINT32]),
|
||||||
makefield("buckets", Ptrto(bucket)),
|
makefield("buckets", ptrto(bucket)),
|
||||||
makefield("oldbuckets", Ptrto(bucket)),
|
makefield("oldbuckets", ptrto(bucket)),
|
||||||
makefield("nevacuate", Types[TUINTPTR]),
|
makefield("nevacuate", Types[TUINTPTR]),
|
||||||
makefield("overflow", Types[TUNSAFEPTR]),
|
makefield("overflow", Types[TUNSAFEPTR]),
|
||||||
}
|
}
|
||||||
@ -226,12 +226,12 @@ func hiter(t *Type) *Type {
|
|||||||
// }
|
// }
|
||||||
// must match ../../../../runtime/hashmap.go:hiter.
|
// must match ../../../../runtime/hashmap.go:hiter.
|
||||||
var field [12]*Field
|
var field [12]*Field
|
||||||
field[0] = makefield("key", Ptrto(t.Key()))
|
field[0] = makefield("key", ptrto(t.Key()))
|
||||||
field[1] = makefield("val", Ptrto(t.Val()))
|
field[1] = makefield("val", ptrto(t.Val()))
|
||||||
field[2] = makefield("t", Ptrto(Types[TUINT8]))
|
field[2] = makefield("t", ptrto(Types[TUINT8]))
|
||||||
field[3] = makefield("h", Ptrto(hmap(t)))
|
field[3] = makefield("h", ptrto(hmap(t)))
|
||||||
field[4] = makefield("buckets", Ptrto(mapbucket(t)))
|
field[4] = makefield("buckets", ptrto(mapbucket(t)))
|
||||||
field[5] = makefield("bptr", Ptrto(mapbucket(t)))
|
field[5] = makefield("bptr", ptrto(mapbucket(t)))
|
||||||
field[6] = makefield("overflow0", Types[TUNSAFEPTR])
|
field[6] = makefield("overflow0", Types[TUNSAFEPTR])
|
||||||
field[7] = makefield("overflow1", Types[TUNSAFEPTR])
|
field[7] = makefield("overflow1", Types[TUNSAFEPTR])
|
||||||
field[8] = makefield("startBucket", Types[TUINTPTR])
|
field[8] = makefield("startBucket", Types[TUINTPTR])
|
||||||
@ -245,7 +245,7 @@ func hiter(t *Type) *Type {
|
|||||||
i.SetFields(field[:])
|
i.SetFields(field[:])
|
||||||
dowidth(i)
|
dowidth(i)
|
||||||
if i.Width != int64(12*Widthptr) {
|
if i.Width != int64(12*Widthptr) {
|
||||||
Yyerror("hash_iter size not correct %d %d", i.Width, 12*Widthptr)
|
yyerror("hash_iter size not correct %d %d", i.Width, 12*Widthptr)
|
||||||
}
|
}
|
||||||
t.MapType().Hiter = i
|
t.MapType().Hiter = i
|
||||||
i.StructType().Map = t
|
i.StructType().Map = t
|
||||||
@ -301,7 +301,7 @@ func methods(t *Type) []*Sig {
|
|||||||
it := t
|
it := t
|
||||||
|
|
||||||
if !isdirectiface(it) {
|
if !isdirectiface(it) {
|
||||||
it = Ptrto(t)
|
it = ptrto(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// make list of methods for t,
|
// make list of methods for t,
|
||||||
@ -830,7 +830,7 @@ func dcommontype(s *Sym, ot int, t *Type) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var sptr *Sym
|
var sptr *Sym
|
||||||
tptr := Ptrto(t)
|
tptr := ptrto(t)
|
||||||
if !t.IsPtr() && (t.Sym != nil || methods(tptr) != nil) {
|
if !t.IsPtr() && (t.Sym != nil || methods(tptr) != nil) {
|
||||||
sptr = dtypesym(tptr)
|
sptr = dtypesym(tptr)
|
||||||
}
|
}
|
||||||
@ -972,7 +972,7 @@ func typenamesym(t *Type) *Sym {
|
|||||||
func typename(t *Type) *Node {
|
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.Addable = true
|
||||||
n.Ullman = 2
|
n.Ullman = 2
|
||||||
n.Typecheck = 1
|
n.Typecheck = 1
|
||||||
@ -995,7 +995,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.Addable = true
|
||||||
n.Ullman = 2
|
n.Ullman = 2
|
||||||
n.Typecheck = 1
|
n.Typecheck = 1
|
||||||
@ -1385,7 +1385,7 @@ func dumptypestructs() {
|
|||||||
t := n.Type
|
t := n.Type
|
||||||
dtypesym(t)
|
dtypesym(t)
|
||||||
if t.Sym != nil {
|
if t.Sym != nil {
|
||||||
dtypesym(Ptrto(t))
|
dtypesym(ptrto(t))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1458,14 +1458,14 @@ func dumptypestructs() {
|
|||||||
// but using runtime means fewer copies in .6 files.
|
// but using runtime means fewer copies in .6 files.
|
||||||
if myimportpath == "runtime" {
|
if myimportpath == "runtime" {
|
||||||
for i := EType(1); i <= TBOOL; i++ {
|
for i := EType(1); i <= TBOOL; i++ {
|
||||||
dtypesym(Ptrto(Types[i]))
|
dtypesym(ptrto(Types[i]))
|
||||||
}
|
}
|
||||||
dtypesym(Ptrto(Types[TSTRING]))
|
dtypesym(ptrto(Types[TSTRING]))
|
||||||
dtypesym(Ptrto(Types[TUNSAFEPTR]))
|
dtypesym(ptrto(Types[TUNSAFEPTR]))
|
||||||
|
|
||||||
// emit type structs for error and func(error) string.
|
// emit type structs for error and func(error) string.
|
||||||
// The latter is the type of an auto-generated wrapper.
|
// The latter is the type of an auto-generated wrapper.
|
||||||
dtypesym(Ptrto(errortype))
|
dtypesym(ptrto(errortype))
|
||||||
|
|
||||||
dtypesym(functype(nil, []*Node{Nod(ODCLFIELD, nil, typenod(errortype))}, []*Node{Nod(ODCLFIELD, nil, typenod(Types[TSTRING]))}))
|
dtypesym(functype(nil, []*Node{Nod(ODCLFIELD, nil, typenod(errortype))}, []*Node{Nod(ODCLFIELD, nil, typenod(Types[TSTRING]))}))
|
||||||
|
|
||||||
@ -1770,7 +1770,7 @@ func zeroaddr(size int64) *Node {
|
|||||||
s.Def = x
|
s.Def = x
|
||||||
}
|
}
|
||||||
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.Addable = true
|
||||||
z.Typecheck = 1
|
z.Typecheck = 1
|
||||||
return z
|
return z
|
||||||
|
@ -24,12 +24,12 @@ func typecheckselect(sel *Node) {
|
|||||||
if ncase.List.Len() == 0 {
|
if ncase.List.Len() == 0 {
|
||||||
// default
|
// default
|
||||||
if def != nil {
|
if def != nil {
|
||||||
Yyerror("multiple defaults in select (first at %v)", def.Line())
|
yyerror("multiple defaults in select (first at %v)", def.Line())
|
||||||
} else {
|
} else {
|
||||||
def = ncase
|
def = ncase
|
||||||
}
|
}
|
||||||
} else if ncase.List.Len() > 1 {
|
} else if ncase.List.Len() > 1 {
|
||||||
Yyerror("select cases cannot be lists")
|
yyerror("select cases cannot be lists")
|
||||||
} else {
|
} else {
|
||||||
ncase.List.SetIndex(0, typecheck(ncase.List.Index(0), Etop))
|
ncase.List.SetIndex(0, typecheck(ncase.List.Index(0), Etop))
|
||||||
n = ncase.List.Index(0)
|
n = ncase.List.Index(0)
|
||||||
@ -38,7 +38,7 @@ func typecheckselect(sel *Node) {
|
|||||||
setlineno(n)
|
setlineno(n)
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
Yyerror("select case must be receive, send or assign recv")
|
yyerror("select case must be receive, send or assign recv")
|
||||||
|
|
||||||
// convert x = <-c into OSELRECV(x, <-c).
|
// convert x = <-c into OSELRECV(x, <-c).
|
||||||
// remove implicit conversions; the eventual assignment
|
// remove implicit conversions; the eventual assignment
|
||||||
@ -49,7 +49,7 @@ func typecheckselect(sel *Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n.Right.Op != ORECV {
|
if n.Right.Op != ORECV {
|
||||||
Yyerror("select assignment must have receive on right hand side")
|
yyerror("select assignment must have receive on right hand side")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ func typecheckselect(sel *Node) {
|
|||||||
// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
|
// convert x, ok = <-c into OSELRECV2(x, <-c) with ntest=ok
|
||||||
case OAS2RECV:
|
case OAS2RECV:
|
||||||
if n.Rlist.First().Op != ORECV {
|
if n.Rlist.First().Op != ORECV {
|
||||||
Yyerror("select assignment must have receive on right hand side")
|
yyerror("select assignment must have receive on right hand side")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +260,7 @@ func walkselect(sel *Node) {
|
|||||||
r = Nod(OAS, selv, nil)
|
r = Nod(OAS, selv, nil)
|
||||||
r = typecheck(r, Etop)
|
r = typecheck(r, Etop)
|
||||||
init = append(init, r)
|
init = append(init, r)
|
||||||
var_ = conv(conv(Nod(OADDR, selv, nil), Types[TUNSAFEPTR]), Ptrto(Types[TUINT8]))
|
var_ = conv(conv(Nod(OADDR, selv, nil), Types[TUNSAFEPTR]), ptrto(Types[TUINT8]))
|
||||||
r = mkcall("newselect", nil, nil, var_, nodintconst(selv.Type.Width), nodintconst(sel.Xoffset))
|
r = mkcall("newselect", nil, nil, var_, nodintconst(selv.Type.Width), nodintconst(sel.Xoffset))
|
||||||
r = typecheck(r, Etop)
|
r = typecheck(r, Etop)
|
||||||
init = append(init, r)
|
init = append(init, r)
|
||||||
@ -324,28 +324,28 @@ func selecttype(size int32) *Type {
|
|||||||
// and then cache; and also cache Select per size.
|
// and then cache; and also cache Select per size.
|
||||||
|
|
||||||
scase := Nod(OTSTRUCT, nil, nil)
|
scase := Nod(OTSTRUCT, nil, nil)
|
||||||
scase.List.Append(Nod(ODCLFIELD, newname(Lookup("elem")), typenod(Ptrto(Types[TUINT8]))))
|
scase.List.Append(Nod(ODCLFIELD, newname(lookup("elem")), typenod(ptrto(Types[TUINT8]))))
|
||||||
scase.List.Append(Nod(ODCLFIELD, newname(Lookup("chan")), typenod(Ptrto(Types[TUINT8]))))
|
scase.List.Append(Nod(ODCLFIELD, newname(lookup("chan")), typenod(ptrto(Types[TUINT8]))))
|
||||||
scase.List.Append(Nod(ODCLFIELD, newname(Lookup("pc")), typenod(Types[TUINTPTR])))
|
scase.List.Append(Nod(ODCLFIELD, newname(lookup("pc")), typenod(Types[TUINTPTR])))
|
||||||
scase.List.Append(Nod(ODCLFIELD, newname(Lookup("kind")), typenod(Types[TUINT16])))
|
scase.List.Append(Nod(ODCLFIELD, newname(lookup("kind")), typenod(Types[TUINT16])))
|
||||||
scase.List.Append(Nod(ODCLFIELD, newname(Lookup("so")), typenod(Types[TUINT16])))
|
scase.List.Append(Nod(ODCLFIELD, newname(lookup("so")), typenod(Types[TUINT16])))
|
||||||
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.Noalg = true
|
||||||
scase.Type.Local = true
|
scase.Type.Local = 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])))
|
||||||
sel.List.Append(Nod(ODCLFIELD, newname(Lookup("ncase")), typenod(Types[TUINT16])))
|
sel.List.Append(Nod(ODCLFIELD, newname(lookup("ncase")), typenod(Types[TUINT16])))
|
||||||
sel.List.Append(Nod(ODCLFIELD, newname(Lookup("pollorder")), typenod(Ptrto(Types[TUINT8]))))
|
sel.List.Append(Nod(ODCLFIELD, newname(lookup("pollorder")), typenod(ptrto(Types[TUINT8]))))
|
||||||
sel.List.Append(Nod(ODCLFIELD, newname(Lookup("lockorder")), typenod(Ptrto(Types[TUINT8]))))
|
sel.List.Append(Nod(ODCLFIELD, newname(lookup("lockorder")), typenod(ptrto(Types[TUINT8]))))
|
||||||
arr := Nod(OTARRAY, nodintconst(int64(size)), scase)
|
arr := Nod(OTARRAY, nodintconst(int64(size)), scase)
|
||||||
sel.List.Append(Nod(ODCLFIELD, newname(Lookup("scase")), arr))
|
sel.List.Append(Nod(ODCLFIELD, newname(lookup("scase")), arr))
|
||||||
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("lockorderarr")), arr))
|
sel.List.Append(Nod(ODCLFIELD, newname(lookup("lockorderarr")), arr))
|
||||||
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.Noalg = true
|
||||||
sel.Type.Local = true
|
sel.Type.Local = true
|
||||||
|
@ -162,7 +162,7 @@ func foundinitloop(node, visited *Node) {
|
|||||||
// those errors probably confused us and
|
// those errors probably confused us and
|
||||||
// there might not be a loop. Let the user
|
// there might not be a loop. Let the user
|
||||||
// fix those first.
|
// fix those first.
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
if nerrors > 0 {
|
if nerrors > 0 {
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
@ -533,7 +533,7 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool {
|
|||||||
*out = append(*out, Nod(OAS, a, val))
|
*out = append(*out, Nod(OAS, a, val))
|
||||||
}
|
}
|
||||||
ptr := Nod(OADDR, a, nil)
|
ptr := Nod(OADDR, a, nil)
|
||||||
n.Type = Ptrto(val.Type)
|
n.Type = ptrto(val.Type)
|
||||||
gdata(&n, ptr, Widthptr)
|
gdata(&n, ptr, Widthptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,7 +571,7 @@ const (
|
|||||||
// Callers should set n.Name.Readonly = true on the
|
// Callers should set n.Name.Readonly = 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))
|
||||||
statuniqgen++
|
statuniqgen++
|
||||||
addvar(n, t, PEXTERN)
|
addvar(n, t, PEXTERN)
|
||||||
return n
|
return n
|
||||||
@ -694,7 +694,7 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
|
|||||||
case OARRAYLIT, OSLICELIT:
|
case OARRAYLIT, OSLICELIT:
|
||||||
indexnode = func(index *Node) *Node { return Nod(OINDEX, var_, index) }
|
indexnode = func(index *Node) *Node { return Nod(OINDEX, var_, index) }
|
||||||
case OSTRUCTLIT:
|
case OSTRUCTLIT:
|
||||||
indexnode = func(index *Node) *Node { return NodSym(ODOT, var_, index.Sym) }
|
indexnode = func(index *Node) *Node { return nodSym(ODOT, var_, index.Sym) }
|
||||||
default:
|
default:
|
||||||
Fatalf("fixedlit bad op: %v", n.Op)
|
Fatalf("fixedlit bad op: %v", n.Op)
|
||||||
}
|
}
|
||||||
@ -805,7 +805,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make new auto *array (3 declare)
|
// make new auto *array (3 declare)
|
||||||
vauto := temp(Ptrto(t))
|
vauto := temp(ptrto(t))
|
||||||
|
|
||||||
// set auto to point at new temp or heap (3 assign)
|
// set auto to point at new temp or heap (3 assign)
|
||||||
var a *Node
|
var a *Node
|
||||||
|
@ -98,7 +98,7 @@ func buildssa(fn *Node) *ssa.Func {
|
|||||||
switch n.Class {
|
switch n.Class {
|
||||||
case PPARAM, PPARAMOUT:
|
case PPARAM, PPARAMOUT:
|
||||||
aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n})
|
aux := s.lookupSymbol(n, &ssa.ArgSymbol{Typ: n.Type, Node: n})
|
||||||
s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sp)
|
s.decladdrs[n] = s.entryNewValue1A(ssa.OpAddr, ptrto(n.Type), aux, s.sp)
|
||||||
if n.Class == PPARAMOUT && s.canSSA(n) {
|
if n.Class == PPARAMOUT && s.canSSA(n) {
|
||||||
// Save ssa-able PPARAMOUT variables so we can
|
// Save ssa-able PPARAMOUT variables so we can
|
||||||
// store them back to the stack at the end of
|
// store them back to the stack at the end of
|
||||||
@ -1412,7 +1412,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OARRAYBYTESTRTMP:
|
case OARRAYBYTESTRTMP:
|
||||||
slice := s.expr(n.Left)
|
slice := s.expr(n.Left)
|
||||||
ptr := s.newValue1(ssa.OpSlicePtr, Ptrto(Types[TUINT8]), slice)
|
ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), slice)
|
||||||
len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice)
|
len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice)
|
||||||
return s.newValue2(ssa.OpStringMake, n.Type, ptr, len)
|
return s.newValue2(ssa.OpStringMake, n.Type, ptr, len)
|
||||||
case OCFUNC:
|
case OCFUNC:
|
||||||
@ -1423,7 +1423,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||||||
// "value" of a function is the address of the function's closure
|
// "value" of a function is the address of the function's closure
|
||||||
sym := funcsym(n.Sym)
|
sym := funcsym(n.Sym)
|
||||||
aux := &ssa.ExternSymbol{Typ: n.Type, Sym: sym}
|
aux := &ssa.ExternSymbol{Typ: n.Type, Sym: sym}
|
||||||
return s.entryNewValue1A(ssa.OpAddr, Ptrto(n.Type), aux, s.sb)
|
return s.entryNewValue1A(ssa.OpAddr, ptrto(n.Type), aux, s.sb)
|
||||||
}
|
}
|
||||||
if s.canSSA(n) {
|
if s.canSSA(n) {
|
||||||
return s.variable(n, n.Type)
|
return s.variable(n, n.Type)
|
||||||
@ -1912,7 +1912,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||||||
s.Fatalf("OINDREG of non-SP register %s in expr: %v", obj.Rconv(int(n.Reg)), n)
|
s.Fatalf("OINDREG of non-SP register %s in expr: %v", obj.Rconv(int(n.Reg)), n)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
addr := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(n.Type), n.Xoffset, s.sp)
|
addr := s.entryNewValue1I(ssa.OpOffPtr, ptrto(n.Type), n.Xoffset, s.sp)
|
||||||
return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem())
|
return s.newValue2(ssa.OpLoad, n.Type, addr, s.mem())
|
||||||
|
|
||||||
case OIND:
|
case OIND:
|
||||||
@ -1943,7 +1943,7 @@ func (s *state) expr(n *Node) *ssa.Value {
|
|||||||
len := s.newValue1(ssa.OpStringLen, Types[TINT], a)
|
len := s.newValue1(ssa.OpStringLen, Types[TINT], a)
|
||||||
s.boundsCheck(i, len)
|
s.boundsCheck(i, len)
|
||||||
}
|
}
|
||||||
ptrtyp := Ptrto(Types[TUINT8])
|
ptrtyp := ptrto(Types[TUINT8])
|
||||||
ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
|
ptr := s.newValue1(ssa.OpStringPtr, ptrtyp, a)
|
||||||
if Isconst(n.Right, CTINT) {
|
if Isconst(n.Right, CTINT) {
|
||||||
ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64(), ptr)
|
ptr = s.newValue1I(ssa.OpOffPtr, ptrtyp, n.Right.Int64(), ptr)
|
||||||
@ -2118,7 +2118,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
|
|||||||
// *(ptr+len+2) = e3
|
// *(ptr+len+2) = e3
|
||||||
|
|
||||||
et := n.Type.Elem()
|
et := n.Type.Elem()
|
||||||
pt := Ptrto(et)
|
pt := ptrto(et)
|
||||||
|
|
||||||
// Evaluate slice
|
// Evaluate slice
|
||||||
sn := n.List.First() // the slice node is the first in the list
|
sn := n.List.First() // the slice node is the first in the list
|
||||||
@ -2234,7 +2234,7 @@ func (s *state) append(n *Node, inplace bool) *ssa.Value {
|
|||||||
if haspointers(et) {
|
if haspointers(et) {
|
||||||
s.insertWBmove(et, addr, arg.v, n.Lineno, arg.isVolatile)
|
s.insertWBmove(et, addr, arg.v, n.Lineno, arg.isVolatile)
|
||||||
} else {
|
} else {
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, SizeAlignAuxInt(et), addr, arg.v, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(et), addr, arg.v, s.mem())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2367,14 +2367,14 @@ func (s *state) assign(left *Node, right *ssa.Value, wb, deref bool, line int32,
|
|||||||
if deref {
|
if deref {
|
||||||
// Treat as a mem->mem move.
|
// Treat as a mem->mem move.
|
||||||
if right == nil {
|
if right == nil {
|
||||||
s.vars[&memVar] = s.newValue2I(ssa.OpZero, ssa.TypeMem, SizeAlignAuxInt(t), addr, s.mem())
|
s.vars[&memVar] = s.newValue2I(ssa.OpZero, ssa.TypeMem, sizeAlignAuxInt(t), addr, s.mem())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if wb {
|
if wb {
|
||||||
s.insertWBmove(t, addr, right, line, rightIsVolatile)
|
s.insertWBmove(t, addr, right, line, rightIsVolatile)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, SizeAlignAuxInt(t), addr, right, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(t), addr, right, s.mem())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Treat as a store.
|
// Treat as a store.
|
||||||
@ -2527,7 +2527,7 @@ func intrinsicInit() {
|
|||||||
// for the backend instead of slicebytetostringtmp calls
|
// for the backend instead of slicebytetostringtmp calls
|
||||||
// when not instrumenting.
|
// when not instrumenting.
|
||||||
slice := s.intrinsicFirstArg(n)
|
slice := s.intrinsicFirstArg(n)
|
||||||
ptr := s.newValue1(ssa.OpSlicePtr, Ptrto(Types[TUINT8]), slice)
|
ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), slice)
|
||||||
len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice)
|
len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice)
|
||||||
return s.newValue2(ssa.OpStringMake, n.Type, ptr, len)
|
return s.newValue2(ssa.OpStringMake, n.Type, ptr, len)
|
||||||
})),
|
})),
|
||||||
@ -2558,9 +2558,9 @@ func intrinsicInit() {
|
|||||||
return s.newValue1(ssa.OpSelect0, Types[TUINT64], v)
|
return s.newValue1(ssa.OpSelect0, Types[TUINT64], v)
|
||||||
}, sys.AMD64, sys.ARM64),
|
}, sys.AMD64, sys.ARM64),
|
||||||
intrinsicKey{"runtime/internal/atomic", "Loadp"}: enableOnArch(func(s *state, n *Node) *ssa.Value {
|
intrinsicKey{"runtime/internal/atomic", "Loadp"}: enableOnArch(func(s *state, n *Node) *ssa.Value {
|
||||||
v := s.newValue2(ssa.OpAtomicLoadPtr, ssa.MakeTuple(Ptrto(Types[TUINT8]), ssa.TypeMem), s.intrinsicArg(n, 0), s.mem())
|
v := s.newValue2(ssa.OpAtomicLoadPtr, ssa.MakeTuple(ptrto(Types[TUINT8]), ssa.TypeMem), s.intrinsicArg(n, 0), s.mem())
|
||||||
s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v)
|
s.vars[&memVar] = s.newValue1(ssa.OpSelect1, ssa.TypeMem, v)
|
||||||
return s.newValue1(ssa.OpSelect0, Ptrto(Types[TUINT8]), v)
|
return s.newValue1(ssa.OpSelect0, ptrto(Types[TUINT8]), v)
|
||||||
}, sys.AMD64, sys.ARM64),
|
}, sys.AMD64, sys.ARM64),
|
||||||
|
|
||||||
intrinsicKey{"runtime/internal/atomic", "Store"}: enableOnArch(func(s *state, n *Node) *ssa.Value {
|
intrinsicKey{"runtime/internal/atomic", "Store"}: enableOnArch(func(s *state, n *Node) *ssa.Value {
|
||||||
@ -2818,7 +2818,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
|
|||||||
s.nilCheck(itab)
|
s.nilCheck(itab)
|
||||||
}
|
}
|
||||||
itabidx := fn.Xoffset + 3*int64(Widthptr) + 8 // offset of fun field in runtime.itab
|
itabidx := fn.Xoffset + 3*int64(Widthptr) + 8 // offset of fun field in runtime.itab
|
||||||
itab = s.newValue1I(ssa.OpOffPtr, Ptrto(Types[TUINTPTR]), itabidx, itab)
|
itab = s.newValue1I(ssa.OpOffPtr, ptrto(Types[TUINTPTR]), itabidx, itab)
|
||||||
if k == callNormal {
|
if k == callNormal {
|
||||||
codeptr = s.newValue2(ssa.OpLoad, Types[TUINTPTR], itab, s.mem())
|
codeptr = s.newValue2(ssa.OpLoad, Types[TUINTPTR], itab, s.mem())
|
||||||
} else {
|
} else {
|
||||||
@ -2841,7 +2841,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
|
|||||||
if k != callNormal {
|
if k != callNormal {
|
||||||
argStart += int64(2 * Widthptr)
|
argStart += int64(2 * Widthptr)
|
||||||
}
|
}
|
||||||
addr := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(Types[TUINTPTR]), argStart, s.sp)
|
addr := s.entryNewValue1I(ssa.OpOffPtr, ptrto(Types[TUINTPTR]), argStart, s.sp)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, rcvr, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, rcvr, s.mem())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2850,9 +2850,9 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
|
|||||||
// Write argsize and closure (args to Newproc/Deferproc).
|
// Write argsize and closure (args to Newproc/Deferproc).
|
||||||
argStart := Ctxt.FixedFrameSize()
|
argStart := Ctxt.FixedFrameSize()
|
||||||
argsize := s.constInt32(Types[TUINT32], int32(stksize))
|
argsize := s.constInt32(Types[TUINT32], int32(stksize))
|
||||||
addr := s.entryNewValue1I(ssa.OpOffPtr, Ptrto(Types[TUINT32]), argStart, s.sp)
|
addr := s.entryNewValue1I(ssa.OpOffPtr, ptrto(Types[TUINT32]), argStart, s.sp)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, 4, addr, argsize, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, 4, addr, argsize, s.mem())
|
||||||
addr = s.entryNewValue1I(ssa.OpOffPtr, Ptrto(Types[TUINTPTR]), argStart+int64(Widthptr), s.sp)
|
addr = s.entryNewValue1I(ssa.OpOffPtr, ptrto(Types[TUINTPTR]), argStart+int64(Widthptr), s.sp)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, closure, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, int64(Widthptr), addr, closure, s.mem())
|
||||||
stksize += 2 * int64(Widthptr)
|
stksize += 2 * int64(Widthptr)
|
||||||
}
|
}
|
||||||
@ -2904,7 +2904,7 @@ func (s *state) call(n *Node, k callKind) *ssa.Value {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
fp := res.Field(0)
|
fp := res.Field(0)
|
||||||
return s.entryNewValue1I(ssa.OpOffPtr, Ptrto(fp.Type), fp.Offset+Ctxt.FixedFrameSize(), s.sp)
|
return s.entryNewValue1I(ssa.OpOffPtr, ptrto(fp.Type), fp.Offset+Ctxt.FixedFrameSize(), s.sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// etypesign returns the signed-ness of e, for integer/pointer etypes.
|
// etypesign returns the signed-ness of e, for integer/pointer etypes.
|
||||||
@ -2945,7 +2945,7 @@ func (s *state) lookupSymbol(n *Node, sym interface{}) interface{} {
|
|||||||
// If bounded is true then this address does not require a nil check for its operand
|
// If bounded is true then this address does not require a nil check for its operand
|
||||||
// even if that would otherwise be implied.
|
// even if that would otherwise be implied.
|
||||||
func (s *state) addr(n *Node, bounded bool) (*ssa.Value, bool) {
|
func (s *state) addr(n *Node, bounded bool) (*ssa.Value, bool) {
|
||||||
t := Ptrto(n.Type)
|
t := ptrto(n.Type)
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case ONAME:
|
case ONAME:
|
||||||
switch n.Class {
|
switch n.Class {
|
||||||
@ -3011,7 +3011,7 @@ func (s *state) addr(n *Node, bounded bool) (*ssa.Value, bool) {
|
|||||||
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), isVolatile
|
return s.newValue2(ssa.OpPtrIndex, ptrto(n.Left.Type.Elem()), a, i), isVolatile
|
||||||
}
|
}
|
||||||
case OIND:
|
case OIND:
|
||||||
return s.exprPtr(n.Left, bounded, n.Lineno), false
|
return s.exprPtr(n.Left, bounded, n.Lineno), false
|
||||||
@ -3023,7 +3023,7 @@ func (s *state) addr(n *Node, bounded bool) (*ssa.Value, bool) {
|
|||||||
return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, p), false
|
return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset, p), false
|
||||||
case OCLOSUREVAR:
|
case OCLOSUREVAR:
|
||||||
return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset,
|
return s.newValue1I(ssa.OpOffPtr, t, n.Xoffset,
|
||||||
s.entryNewValue0(ssa.OpGetClosurePtr, Ptrto(Types[TUINT8]))), false
|
s.entryNewValue0(ssa.OpGetClosurePtr, ptrto(Types[TUINT8]))), false
|
||||||
case OCONVNOP:
|
case OCONVNOP:
|
||||||
addr, isVolatile := s.addr(n.Left, bounded)
|
addr, isVolatile := s.addr(n.Left, bounded)
|
||||||
return s.newValue1(ssa.OpCopy, t, addr), isVolatile // ensure that addr has the right type
|
return s.newValue1(ssa.OpCopy, t, addr), isVolatile // ensure that addr has the right type
|
||||||
@ -3255,7 +3255,7 @@ func (s *state) rtcall(fn *Node, returns bool, results []*Type, args ...*ssa.Val
|
|||||||
off = Rnd(off, t.Alignment())
|
off = Rnd(off, t.Alignment())
|
||||||
ptr := s.sp
|
ptr := s.sp
|
||||||
if off != 0 {
|
if off != 0 {
|
||||||
ptr = s.newValue1I(ssa.OpOffPtr, Ptrto(t), off, s.sp)
|
ptr = s.newValue1I(ssa.OpOffPtr, ptrto(t), off, s.sp)
|
||||||
}
|
}
|
||||||
res[i] = s.newValue2(ssa.OpLoad, t, ptr, s.mem())
|
res[i] = s.newValue2(ssa.OpLoad, t, ptr, s.mem())
|
||||||
off += t.Size()
|
off += t.Size()
|
||||||
@ -3288,7 +3288,7 @@ func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line int32, rightI
|
|||||||
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
||||||
|
|
||||||
aux := &ssa.ExternSymbol{Typ: Types[TBOOL], Sym: syslook("writeBarrier").Sym}
|
aux := &ssa.ExternSymbol{Typ: Types[TBOOL], Sym: syslook("writeBarrier").Sym}
|
||||||
flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TUINT32]), aux, s.sb)
|
flagaddr := s.newValue1A(ssa.OpAddr, ptrto(Types[TUINT32]), aux, s.sb)
|
||||||
// Load word, test word, avoiding partial register write from load byte.
|
// Load word, test word, avoiding partial register write from load byte.
|
||||||
flag := s.newValue2(ssa.OpLoad, Types[TUINT32], flagaddr, s.mem())
|
flag := s.newValue2(ssa.OpLoad, Types[TUINT32], flagaddr, s.mem())
|
||||||
flag = s.newValue2(ssa.OpNeq32, Types[TBOOL], flag, s.constInt32(Types[TUINT32], 0))
|
flag = s.newValue2(ssa.OpNeq32, Types[TBOOL], flag, s.constInt32(Types[TUINT32], 0))
|
||||||
@ -3312,7 +3312,7 @@ func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line int32, rightI
|
|||||||
tmp := temp(t)
|
tmp := temp(t)
|
||||||
s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, tmp, s.mem())
|
s.vars[&memVar] = s.newValue1A(ssa.OpVarDef, ssa.TypeMem, tmp, s.mem())
|
||||||
tmpaddr, _ := s.addr(tmp, true)
|
tmpaddr, _ := s.addr(tmp, true)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, SizeAlignAuxInt(t), tmpaddr, right, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(t), tmpaddr, right, s.mem())
|
||||||
// Issue typedmemmove call.
|
// Issue typedmemmove call.
|
||||||
taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], &ssa.ExternSymbol{Typ: Types[TUINTPTR], Sym: typenamesym(t)}, s.sb)
|
taddr := s.newValue1A(ssa.OpAddr, Types[TUINTPTR], &ssa.ExternSymbol{Typ: Types[TUINTPTR], Sym: typenamesym(t)}, s.sb)
|
||||||
s.rtcall(typedmemmove, true, nil, taddr, left, tmpaddr)
|
s.rtcall(typedmemmove, true, nil, taddr, left, tmpaddr)
|
||||||
@ -3322,7 +3322,7 @@ func (s *state) insertWBmove(t *Type, left, right *ssa.Value, line int32, rightI
|
|||||||
s.endBlock().AddEdgeTo(bEnd)
|
s.endBlock().AddEdgeTo(bEnd)
|
||||||
|
|
||||||
s.startBlock(bElse)
|
s.startBlock(bElse)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, SizeAlignAuxInt(t), left, right, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpMove, ssa.TypeMem, sizeAlignAuxInt(t), left, right, s.mem())
|
||||||
s.endBlock().AddEdgeTo(bEnd)
|
s.endBlock().AddEdgeTo(bEnd)
|
||||||
|
|
||||||
s.startBlock(bEnd)
|
s.startBlock(bEnd)
|
||||||
@ -3355,7 +3355,7 @@ func (s *state) insertWBstore(t *Type, left, right *ssa.Value, line int32, skip
|
|||||||
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
bEnd := s.f.NewBlock(ssa.BlockPlain)
|
||||||
|
|
||||||
aux := &ssa.ExternSymbol{Typ: Types[TBOOL], Sym: syslook("writeBarrier").Sym}
|
aux := &ssa.ExternSymbol{Typ: Types[TBOOL], Sym: syslook("writeBarrier").Sym}
|
||||||
flagaddr := s.newValue1A(ssa.OpAddr, Ptrto(Types[TUINT32]), aux, s.sb)
|
flagaddr := s.newValue1A(ssa.OpAddr, ptrto(Types[TUINT32]), aux, s.sb)
|
||||||
// Load word, test word, avoiding partial register write from load byte.
|
// Load word, test word, avoiding partial register write from load byte.
|
||||||
flag := s.newValue2(ssa.OpLoad, Types[TUINT32], flagaddr, s.mem())
|
flag := s.newValue2(ssa.OpLoad, Types[TUINT32], flagaddr, s.mem())
|
||||||
flag = s.newValue2(ssa.OpNeq32, Types[TBOOL], flag, s.constInt32(Types[TUINT32], 0))
|
flag = s.newValue2(ssa.OpNeq32, Types[TBOOL], flag, s.constInt32(Types[TUINT32], 0))
|
||||||
@ -3395,22 +3395,22 @@ func (s *state) storeTypeScalars(t *Type, left, right *ssa.Value, skip skipMask)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
len := s.newValue1(ssa.OpStringLen, Types[TINT], right)
|
len := s.newValue1(ssa.OpStringLen, Types[TINT], right)
|
||||||
lenAddr := s.newValue1I(ssa.OpOffPtr, Ptrto(Types[TINT]), s.config.IntSize, left)
|
lenAddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TINT]), s.config.IntSize, left)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
|
||||||
case t.IsSlice():
|
case t.IsSlice():
|
||||||
if skip&skipLen == 0 {
|
if skip&skipLen == 0 {
|
||||||
len := s.newValue1(ssa.OpSliceLen, Types[TINT], right)
|
len := s.newValue1(ssa.OpSliceLen, Types[TINT], right)
|
||||||
lenAddr := s.newValue1I(ssa.OpOffPtr, Ptrto(Types[TINT]), s.config.IntSize, left)
|
lenAddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TINT]), s.config.IntSize, left)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, lenAddr, len, s.mem())
|
||||||
}
|
}
|
||||||
if skip&skipCap == 0 {
|
if skip&skipCap == 0 {
|
||||||
cap := s.newValue1(ssa.OpSliceCap, Types[TINT], right)
|
cap := s.newValue1(ssa.OpSliceCap, Types[TINT], right)
|
||||||
capAddr := s.newValue1I(ssa.OpOffPtr, Ptrto(Types[TINT]), 2*s.config.IntSize, left)
|
capAddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TINT]), 2*s.config.IntSize, left)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capAddr, cap, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, capAddr, cap, s.mem())
|
||||||
}
|
}
|
||||||
case t.IsInterface():
|
case t.IsInterface():
|
||||||
// itab field doesn't need a write barrier (even though it is a pointer).
|
// itab field doesn't need a write barrier (even though it is a pointer).
|
||||||
itab := s.newValue1(ssa.OpITab, Ptrto(Types[TUINT8]), right)
|
itab := s.newValue1(ssa.OpITab, ptrto(Types[TUINT8]), right)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, left, itab, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.IntSize, left, itab, s.mem())
|
||||||
case t.IsStruct():
|
case t.IsStruct():
|
||||||
n := t.NumFields()
|
n := t.NumFields()
|
||||||
@ -3431,15 +3431,15 @@ func (s *state) storeTypePtrs(t *Type, left, right *ssa.Value) {
|
|||||||
case t.IsPtrShaped():
|
case t.IsPtrShaped():
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, right, s.mem())
|
||||||
case t.IsString():
|
case t.IsString():
|
||||||
ptr := s.newValue1(ssa.OpStringPtr, Ptrto(Types[TUINT8]), right)
|
ptr := s.newValue1(ssa.OpStringPtr, ptrto(Types[TUINT8]), right)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
|
||||||
case t.IsSlice():
|
case t.IsSlice():
|
||||||
ptr := s.newValue1(ssa.OpSlicePtr, Ptrto(Types[TUINT8]), right)
|
ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), right)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, left, ptr, s.mem())
|
||||||
case t.IsInterface():
|
case t.IsInterface():
|
||||||
// itab field is treated as a scalar.
|
// itab field is treated as a scalar.
|
||||||
idata := s.newValue1(ssa.OpIData, Ptrto(Types[TUINT8]), right)
|
idata := s.newValue1(ssa.OpIData, ptrto(Types[TUINT8]), right)
|
||||||
idataAddr := s.newValue1I(ssa.OpOffPtr, Ptrto(Types[TUINT8]), s.config.PtrSize, left)
|
idataAddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TUINT8]), s.config.PtrSize, left)
|
||||||
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, idataAddr, idata, s.mem())
|
s.vars[&memVar] = s.newValue3I(ssa.OpStore, ssa.TypeMem, s.config.PtrSize, idataAddr, idata, s.mem())
|
||||||
case t.IsStruct():
|
case t.IsStruct():
|
||||||
n := t.NumFields()
|
n := t.NumFields()
|
||||||
@ -3463,14 +3463,14 @@ func (s *state) storeTypePtrsWB(t *Type, left, right *ssa.Value) {
|
|||||||
case t.IsPtrShaped():
|
case t.IsPtrShaped():
|
||||||
s.rtcall(writebarrierptr, true, nil, left, right)
|
s.rtcall(writebarrierptr, true, nil, left, right)
|
||||||
case t.IsString():
|
case t.IsString():
|
||||||
ptr := s.newValue1(ssa.OpStringPtr, Ptrto(Types[TUINT8]), right)
|
ptr := s.newValue1(ssa.OpStringPtr, ptrto(Types[TUINT8]), right)
|
||||||
s.rtcall(writebarrierptr, true, nil, left, ptr)
|
s.rtcall(writebarrierptr, true, nil, left, ptr)
|
||||||
case t.IsSlice():
|
case t.IsSlice():
|
||||||
ptr := s.newValue1(ssa.OpSlicePtr, Ptrto(Types[TUINT8]), right)
|
ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), right)
|
||||||
s.rtcall(writebarrierptr, true, nil, left, ptr)
|
s.rtcall(writebarrierptr, true, nil, left, ptr)
|
||||||
case t.IsInterface():
|
case t.IsInterface():
|
||||||
idata := s.newValue1(ssa.OpIData, Ptrto(Types[TUINT8]), right)
|
idata := s.newValue1(ssa.OpIData, ptrto(Types[TUINT8]), right)
|
||||||
idataAddr := s.newValue1I(ssa.OpOffPtr, Ptrto(Types[TUINT8]), s.config.PtrSize, left)
|
idataAddr := s.newValue1I(ssa.OpOffPtr, ptrto(Types[TUINT8]), s.config.PtrSize, left)
|
||||||
s.rtcall(writebarrierptr, true, nil, idataAddr, idata)
|
s.rtcall(writebarrierptr, true, nil, idataAddr, idata)
|
||||||
case t.IsStruct():
|
case t.IsStruct():
|
||||||
n := t.NumFields()
|
n := t.NumFields()
|
||||||
@ -3501,13 +3501,13 @@ func (s *state) slice(t *Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) {
|
|||||||
switch {
|
switch {
|
||||||
case t.IsSlice():
|
case t.IsSlice():
|
||||||
elemtype = t.Elem()
|
elemtype = t.Elem()
|
||||||
ptrtype = Ptrto(elemtype)
|
ptrtype = ptrto(elemtype)
|
||||||
ptr = s.newValue1(ssa.OpSlicePtr, ptrtype, v)
|
ptr = s.newValue1(ssa.OpSlicePtr, ptrtype, v)
|
||||||
len = s.newValue1(ssa.OpSliceLen, Types[TINT], v)
|
len = s.newValue1(ssa.OpSliceLen, Types[TINT], v)
|
||||||
cap = s.newValue1(ssa.OpSliceCap, Types[TINT], v)
|
cap = s.newValue1(ssa.OpSliceCap, Types[TINT], v)
|
||||||
case t.IsString():
|
case t.IsString():
|
||||||
elemtype = Types[TUINT8]
|
elemtype = Types[TUINT8]
|
||||||
ptrtype = Ptrto(elemtype)
|
ptrtype = ptrto(elemtype)
|
||||||
ptr = s.newValue1(ssa.OpStringPtr, ptrtype, v)
|
ptr = s.newValue1(ssa.OpStringPtr, ptrtype, v)
|
||||||
len = s.newValue1(ssa.OpStringLen, Types[TINT], v)
|
len = s.newValue1(ssa.OpStringLen, Types[TINT], v)
|
||||||
cap = len
|
cap = len
|
||||||
@ -3516,7 +3516,7 @@ func (s *state) slice(t *Type, v, i, j, k *ssa.Value) (p, l, c *ssa.Value) {
|
|||||||
s.Fatalf("bad ptr to array in slice %v\n", t)
|
s.Fatalf("bad ptr to array in slice %v\n", t)
|
||||||
}
|
}
|
||||||
elemtype = t.Elem().Elem()
|
elemtype = t.Elem().Elem()
|
||||||
ptrtype = Ptrto(elemtype)
|
ptrtype = ptrto(elemtype)
|
||||||
s.nilCheck(v)
|
s.nilCheck(v)
|
||||||
ptr = v
|
ptr = v
|
||||||
len = s.constInt(Types[TINT], t.Elem().NumElem())
|
len = s.constInt(Types[TINT], t.Elem().NumElem())
|
||||||
@ -3821,7 +3821,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n *Node, x *ssa.Value, ft, tt *Ty
|
|||||||
// n is the node for the interface expression.
|
// n is the node for the interface expression.
|
||||||
// v is the corresponding value.
|
// v is the corresponding value.
|
||||||
func (s *state) ifaceType(n *Node, v *ssa.Value) *ssa.Value {
|
func (s *state) ifaceType(n *Node, v *ssa.Value) *ssa.Value {
|
||||||
byteptr := Ptrto(Types[TUINT8]) // type used in runtime prototypes for runtime type (*byte)
|
byteptr := ptrto(Types[TUINT8]) // type used in runtime prototypes for runtime type (*byte)
|
||||||
|
|
||||||
if n.Type.IsEmptyInterface() {
|
if n.Type.IsEmptyInterface() {
|
||||||
// Have *eface. The type is the first word in the struct.
|
// Have *eface. The type is the first word in the struct.
|
||||||
@ -3883,7 +3883,7 @@ func (s *state) dottype(n *Node, commaok bool) (res, resok *ssa.Value) {
|
|||||||
b.SetControl(cond)
|
b.SetControl(cond)
|
||||||
b.Likely = ssa.BranchLikely
|
b.Likely = ssa.BranchLikely
|
||||||
|
|
||||||
byteptr := Ptrto(Types[TUINT8])
|
byteptr := ptrto(Types[TUINT8])
|
||||||
|
|
||||||
bOk := s.f.NewBlock(ssa.BlockPlain)
|
bOk := s.f.NewBlock(ssa.BlockPlain)
|
||||||
bFail := s.f.NewBlock(ssa.BlockPlain)
|
bFail := s.f.NewBlock(ssa.BlockPlain)
|
||||||
@ -4402,8 +4402,8 @@ func AddAux2(a *obj.Addr, v *ssa.Value, offset int64) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SizeAlignAuxInt returns an AuxInt encoding the size and alignment of type t.
|
// sizeAlignAuxInt returns an AuxInt encoding the size and alignment of type t.
|
||||||
func SizeAlignAuxInt(t *Type) int64 {
|
func sizeAlignAuxInt(t *Type) int64 {
|
||||||
return ssa.MakeSizeAndAlign(t.Size(), t.Alignment()).Int64()
|
return ssa.MakeSizeAndAlign(t.Size(), t.Alignment()).Int64()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4604,7 +4604,7 @@ func (s *ssaExport) TypeFloat64() ssa.Type { return Types[TFLOAT64] }
|
|||||||
func (s *ssaExport) TypeInt() ssa.Type { return Types[TINT] }
|
func (s *ssaExport) TypeInt() ssa.Type { return Types[TINT] }
|
||||||
func (s *ssaExport) TypeUintptr() ssa.Type { return Types[TUINTPTR] }
|
func (s *ssaExport) TypeUintptr() ssa.Type { return Types[TUINTPTR] }
|
||||||
func (s *ssaExport) TypeString() ssa.Type { return Types[TSTRING] }
|
func (s *ssaExport) TypeString() ssa.Type { return Types[TSTRING] }
|
||||||
func (s *ssaExport) TypeBytePtr() ssa.Type { return Ptrto(Types[TUINT8]) }
|
func (s *ssaExport) TypeBytePtr() ssa.Type { return ptrto(Types[TUINT8]) }
|
||||||
|
|
||||||
// StringData returns a symbol (a *Sym wrapped in an interface) which
|
// StringData returns a symbol (a *Sym wrapped in an interface) which
|
||||||
// is the data component of a global string constant containing s.
|
// is the data component of a global string constant containing s.
|
||||||
@ -4621,7 +4621,7 @@ func (e *ssaExport) Auto(t ssa.Type) ssa.GCNode {
|
|||||||
|
|
||||||
func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
|
func (e *ssaExport) SplitString(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot) {
|
||||||
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.
|
||||||
@ -4635,7 +4635,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"
|
||||||
@ -4652,7 +4652,7 @@ func (e *ssaExport) SplitInterface(name ssa.LocalSlot) (ssa.LocalSlot, ssa.Local
|
|||||||
|
|
||||||
func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (ssa.LocalSlot, ssa.LocalSlot, ssa.LocalSlot) {
|
func (e *ssaExport) SplitSlice(name ssa.LocalSlot) (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.
|
||||||
|
@ -27,7 +27,7 @@ type Error struct {
|
|||||||
var errors []Error
|
var errors []Error
|
||||||
|
|
||||||
func errorexit() {
|
func errorexit() {
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
if outfile != "" {
|
if outfile != "" {
|
||||||
os.Remove(outfile)
|
os.Remove(outfile)
|
||||||
}
|
}
|
||||||
@ -58,7 +58,7 @@ func (x byLineno) Len() int { return len(x) }
|
|||||||
func (x byLineno) Less(i, j int) bool { return x[i].lineno < x[j].lineno }
|
func (x byLineno) Less(i, j int) bool { return x[i].lineno < x[j].lineno }
|
||||||
func (x byLineno) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
func (x byLineno) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||||
|
|
||||||
func Flusherrors() {
|
func flusherrors() {
|
||||||
Ctxt.Bso.Flush()
|
Ctxt.Bso.Flush()
|
||||||
if len(errors) == 0 {
|
if len(errors) == 0 {
|
||||||
return
|
return
|
||||||
@ -74,7 +74,7 @@ func Flusherrors() {
|
|||||||
|
|
||||||
func hcrash() {
|
func hcrash() {
|
||||||
if Debug['h'] != 0 {
|
if Debug['h'] != 0 {
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
if outfile != "" {
|
if outfile != "" {
|
||||||
os.Remove(outfile)
|
os.Remove(outfile)
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ func yyerrorl(line int32, format string, args ...interface{}) {
|
|||||||
lasterror.syntax = line
|
lasterror.syntax = line
|
||||||
} else {
|
} else {
|
||||||
// only one of multiple equal non-syntax errors per line
|
// only one of multiple equal non-syntax errors per line
|
||||||
// (Flusherrors shows only one of them, so we filter them
|
// (flusherrors shows only one of them, so we filter them
|
||||||
// here as best as we can (they may not appear in order)
|
// here as best as we can (they may not appear in order)
|
||||||
// so that we don't count them here and exit early, and
|
// so that we don't count them here and exit early, and
|
||||||
// then have nothing to show for.)
|
// then have nothing to show for.)
|
||||||
@ -124,13 +124,13 @@ func yyerrorl(line int32, format string, args ...interface{}) {
|
|||||||
hcrash()
|
hcrash()
|
||||||
nerrors++
|
nerrors++
|
||||||
if nsavederrors+nerrors >= 10 && Debug['e'] == 0 {
|
if nsavederrors+nerrors >= 10 && Debug['e'] == 0 {
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
fmt.Printf("%v: too many errors\n", linestr(line))
|
fmt.Printf("%v: too many errors\n", linestr(line))
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Yyerror(format string, args ...interface{}) {
|
func yyerror(format string, args ...interface{}) {
|
||||||
yyerrorl(lineno, format, args...)
|
yyerrorl(lineno, format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,12 +143,12 @@ func Warn(fmt_ string, args ...interface{}) {
|
|||||||
func Warnl(line int32, fmt_ string, args ...interface{}) {
|
func Warnl(line int32, fmt_ string, args ...interface{}) {
|
||||||
adderr(line, fmt_, args...)
|
adderr(line, fmt_, args...)
|
||||||
if Debug['m'] != 0 {
|
if Debug['m'] != 0 {
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Fatalf(fmt_ string, args ...interface{}) {
|
func Fatalf(fmt_ string, args ...interface{}) {
|
||||||
Flusherrors()
|
flusherrors()
|
||||||
|
|
||||||
fmt.Printf("%v: internal compiler error: ", linestr(lineno))
|
fmt.Printf("%v: internal compiler error: ", linestr(lineno))
|
||||||
fmt.Printf(fmt_, args...)
|
fmt.Printf(fmt_, args...)
|
||||||
@ -225,25 +225,25 @@ func setlineno(n *Node) int32 {
|
|||||||
return lno
|
return lno
|
||||||
}
|
}
|
||||||
|
|
||||||
func Lookup(name string) *Sym {
|
func lookup(name string) *Sym {
|
||||||
return localpkg.Lookup(name)
|
return localpkg.Lookup(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Lookupf(format string, a ...interface{}) *Sym {
|
func lookupf(format string, a ...interface{}) *Sym {
|
||||||
return Lookup(fmt.Sprintf(format, a...))
|
return lookup(fmt.Sprintf(format, a...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func LookupBytes(name []byte) *Sym {
|
func lookupBytes(name []byte) *Sym {
|
||||||
return localpkg.LookupBytes(name)
|
return localpkg.LookupBytes(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LookupN looks up the symbol starting with prefix and ending with
|
// lookupN looks up the symbol starting with prefix and ending with
|
||||||
// the decimal n. If prefix is too long, LookupN panics.
|
// the decimal n. If prefix is too long, lookupN panics.
|
||||||
func LookupN(prefix string, n int) *Sym {
|
func lookupN(prefix string, n int) *Sym {
|
||||||
var buf [20]byte // plenty long enough for all current users
|
var buf [20]byte // plenty long enough for all current users
|
||||||
copy(buf[:], prefix)
|
copy(buf[:], prefix)
|
||||||
b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
|
b := strconv.AppendInt(buf[:len(prefix)], int64(n), 10)
|
||||||
return LookupBytes(b)
|
return lookupBytes(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// autolabel generates a new Name node for use with
|
// autolabel generates a new Name node for use with
|
||||||
@ -262,7 +262,7 @@ func autolabel(prefix string) *Node {
|
|||||||
}
|
}
|
||||||
n := fn.Func.Label
|
n := fn.Func.Label
|
||||||
fn.Func.Label++
|
fn.Func.Label++
|
||||||
return newname(LookupN(prefix, int(n)))
|
return newname(lookupN(prefix, int(n)))
|
||||||
}
|
}
|
||||||
|
|
||||||
var initSyms []*Sym
|
var initSyms []*Sym
|
||||||
@ -307,7 +307,7 @@ func Pkglookup(name string, pkg *Pkg) *Sym {
|
|||||||
|
|
||||||
func restrictlookup(name string, pkg *Pkg) *Sym {
|
func restrictlookup(name string, pkg *Pkg) *Sym {
|
||||||
if !exportname(name) && pkg != localpkg {
|
if !exportname(name) && pkg != localpkg {
|
||||||
Yyerror("cannot refer to unexported name %s.%s", pkg.Name, name)
|
yyerror("cannot refer to unexported name %s.%s", pkg.Name, name)
|
||||||
}
|
}
|
||||||
return Pkglookup(name, pkg)
|
return Pkglookup(name, pkg)
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ func importdot(opkg *Pkg, pack *Node) {
|
|||||||
if !exportname(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot
|
if !exportname(s.Name) || strings.ContainsRune(s.Name, 0xb7) { // 0xb7 = center dot
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s1 = Lookup(s.Name)
|
s1 = lookup(s.Name)
|
||||||
if s1.Def != nil {
|
if s1.Def != nil {
|
||||||
pkgerror = fmt.Sprintf("during import %q", opkg.Path)
|
pkgerror = fmt.Sprintf("during import %q", opkg.Path)
|
||||||
redeclare(s1, pkgerror)
|
redeclare(s1, pkgerror)
|
||||||
@ -381,9 +381,9 @@ func Nod(op Op, nleft *Node, nright *Node) *Node {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodSym makes a Node with Op op and with the Left field set to left
|
// nodSym makes a Node with Op op and with the Left field set to left
|
||||||
// and the Sym field set to sym. This is for ODOT and friends.
|
// and the Sym field set to sym. This is for ODOT and friends.
|
||||||
func NodSym(op Op, left *Node, sym *Sym) *Node {
|
func nodSym(op Op, left *Node, sym *Sym) *Node {
|
||||||
n := Nod(op, left, nil)
|
n := Nod(op, left, nil)
|
||||||
n.Sym = sym
|
n.Sym = sym
|
||||||
return n
|
return n
|
||||||
@ -468,7 +468,7 @@ func nodnil() *Node {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func Nodbool(b bool) *Node {
|
func nodbool(b bool) *Node {
|
||||||
c := nodintconst(0)
|
c := nodintconst(0)
|
||||||
c.SetVal(Val{b})
|
c.SetVal(Val{b})
|
||||||
c.Type = idealbool
|
c.Type = idealbool
|
||||||
@ -482,13 +482,13 @@ func aindex(b *Node, t *Type) *Type {
|
|||||||
if b != nil {
|
if b != nil {
|
||||||
switch consttype(b) {
|
switch consttype(b) {
|
||||||
default:
|
default:
|
||||||
Yyerror("array bound must be an integer expression")
|
yyerror("array bound must be an integer expression")
|
||||||
|
|
||||||
case CTINT, CTRUNE:
|
case CTINT, CTRUNE:
|
||||||
hasbound = true
|
hasbound = true
|
||||||
bound = b.Int64()
|
bound = b.Int64()
|
||||||
if bound < 0 {
|
if bound < 0 {
|
||||||
Yyerror("array bound must be non negative")
|
yyerror("array bound must be non negative")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,7 +526,7 @@ func treecopy(n *Node, lineno int32) *Node {
|
|||||||
return &m
|
return &m
|
||||||
|
|
||||||
case ONONAME:
|
case ONONAME:
|
||||||
if n.Sym == Lookup("iota") {
|
if n.Sym == lookup("iota") {
|
||||||
// Not sure yet whether this is the real iota,
|
// Not sure yet whether this is the real iota,
|
||||||
// but make a copy of the Node* just in case,
|
// but make a copy of the Node* just in case,
|
||||||
// so that all the copies of this const definition
|
// so that all the copies of this const definition
|
||||||
@ -681,8 +681,8 @@ func eqtype1(t1, t2 *Type, assumedEqual map[typePair]struct{}) bool {
|
|||||||
|
|
||||||
switch t1.Etype {
|
switch t1.Etype {
|
||||||
case TINTER, TSTRUCT:
|
case TINTER, TSTRUCT:
|
||||||
t1, i1 := IterFields(t1)
|
t1, i1 := iterFields(t1)
|
||||||
t2, i2 := IterFields(t2)
|
t2, i2 := iterFields(t2)
|
||||||
for ; t1 != nil && t2 != nil; t1, t2 = i1.Next(), i2.Next() {
|
for ; t1 != nil && t2 != nil; t1, t2 = i1.Next(), i2.Next() {
|
||||||
if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, assumedEqual) || t1.Note != t2.Note {
|
if t1.Sym != t2.Sym || t1.Embedded != t2.Embedded || !eqtype1(t1.Type, t2.Type, assumedEqual) || t1.Note != t2.Note {
|
||||||
return false
|
return false
|
||||||
@ -700,8 +700,8 @@ func eqtype1(t1, t2 *Type, assumedEqual map[typePair]struct{}) bool {
|
|||||||
// equality, because they're never relevant.
|
// equality, because they're never relevant.
|
||||||
for _, f := range paramsResults {
|
for _, f := range paramsResults {
|
||||||
// Loop over fields in structs, ignoring argument names.
|
// Loop over fields in structs, ignoring argument names.
|
||||||
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, assumedEqual) {
|
if ta.Isddd != tb.Isddd || !eqtype1(ta.Type, tb.Type, assumedEqual) {
|
||||||
return false
|
return false
|
||||||
@ -741,8 +741,8 @@ func eqtypenoname(t1 *Type, t2 *Type) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
f1, i1 := IterFields(t1)
|
f1, i1 := iterFields(t1)
|
||||||
f2, i2 := IterFields(t2)
|
f2, i2 := iterFields(t2)
|
||||||
for {
|
for {
|
||||||
if !eqtype(f1.Type, f2.Type) {
|
if !eqtype(f1.Type, f2.Type) {
|
||||||
return false
|
return false
|
||||||
@ -766,7 +766,7 @@ func assignop(src *Type, dst *Type, why *string) Op {
|
|||||||
// TODO(rsc,lvd): This behaves poorly in the presence of inlining.
|
// TODO(rsc,lvd): This behaves poorly in the presence of inlining.
|
||||||
// https://golang.org/issue/2795
|
// https://golang.org/issue/2795
|
||||||
if safemode && importpkg == nil && src != nil && src.Etype == TUNSAFEPTR {
|
if safemode && importpkg == nil && src != nil && src.Etype == TUNSAFEPTR {
|
||||||
Yyerror("cannot use unsafe.Pointer")
|
yyerror("cannot use unsafe.Pointer")
|
||||||
errorexit()
|
errorexit()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -985,7 +985,7 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if t.Etype == TBLANK && n.Type.Etype == TNIL {
|
if t.Etype == TBLANK && n.Type.Etype == TNIL {
|
||||||
Yyerror("use of untyped nil")
|
yyerror("use of untyped nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
old := n
|
old := n
|
||||||
@ -1015,7 +1015,7 @@ func assignconvfn(n *Node, t *Type, context func() string) *Node {
|
|||||||
var why string
|
var why string
|
||||||
op := assignop(n.Type, t, &why)
|
op := assignop(n.Type, t, &why)
|
||||||
if op == 0 {
|
if op == 0 {
|
||||||
Yyerror("cannot use %L as type %v in %s%s", n, t, context(), why)
|
yyerror("cannot use %L as type %v in %s%s", n, t, context(), why)
|
||||||
op = OCONV
|
op = OCONV
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1135,9 +1135,9 @@ func initPtrto() {
|
|||||||
ptrToInt32 = typPtr(Types[TINT32])
|
ptrToInt32 = typPtr(Types[TINT32])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ptrto returns the Type *t.
|
// ptrto returns the Type *t.
|
||||||
// The returned struct must not be modified.
|
// The returned struct must not be modified.
|
||||||
func Ptrto(t *Type) *Type {
|
func ptrto(t *Type) *Type {
|
||||||
if Tptr == 0 {
|
if Tptr == 0 {
|
||||||
Fatalf("ptrto: no tptr")
|
Fatalf("ptrto: no tptr")
|
||||||
}
|
}
|
||||||
@ -1268,12 +1268,12 @@ func badtype(op Op, tl *Type, tr *Type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s := fmt_
|
s := fmt_
|
||||||
Yyerror("illegal types for operand: %v%s", op, s)
|
yyerror("illegal types for operand: %v%s", op, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Brcom returns !(op).
|
// brcom returns !(op).
|
||||||
// For example, Brcom(==) is !=.
|
// For example, brcom(==) is !=.
|
||||||
func Brcom(op Op) Op {
|
func brcom(op Op) Op {
|
||||||
switch op {
|
switch op {
|
||||||
case OEQ:
|
case OEQ:
|
||||||
return ONE
|
return ONE
|
||||||
@ -1292,9 +1292,9 @@ func Brcom(op Op) Op {
|
|||||||
return op
|
return op
|
||||||
}
|
}
|
||||||
|
|
||||||
// Brrev returns reverse(op).
|
// brrev returns reverse(op).
|
||||||
// For example, Brrev(<) is >.
|
// For example, Brrev(<) is >.
|
||||||
func Brrev(op Op) Op {
|
func brrev(op Op) Op {
|
||||||
switch op {
|
switch op {
|
||||||
case OEQ:
|
case OEQ:
|
||||||
return OEQ
|
return OEQ
|
||||||
@ -1553,11 +1553,11 @@ func adddot(n *Node) *Node {
|
|||||||
case path != nil:
|
case path != nil:
|
||||||
// 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.Implicit = true
|
||||||
}
|
}
|
||||||
case ambig:
|
case ambig:
|
||||||
Yyerror("ambiguous selector %v", n)
|
yyerror("ambiguous selector %v", n)
|
||||||
n.Left = nil
|
n.Left = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1702,7 +1702,7 @@ func structargs(tl *Type, mustname bool) []*Node {
|
|||||||
// invent a name so that we can refer to it in the trampoline
|
// invent a name so that we can refer to it in the trampoline
|
||||||
buf := fmt.Sprintf(".anon%d", gen)
|
buf := fmt.Sprintf(".anon%d", gen)
|
||||||
gen++
|
gen++
|
||||||
n = newname(Lookup(buf))
|
n = newname(lookup(buf))
|
||||||
} else if t.Sym != nil {
|
} else if t.Sym != nil {
|
||||||
n = newname(t.Sym)
|
n = newname(t.Sym)
|
||||||
}
|
}
|
||||||
@ -1758,7 +1758,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
|
|||||||
dclcontext = PEXTERN
|
dclcontext = PEXTERN
|
||||||
markdcl()
|
markdcl()
|
||||||
|
|
||||||
this := Nod(ODCLFIELD, newname(Lookup(".this")), typenod(rcvr))
|
this := Nod(ODCLFIELD, newname(lookup(".this")), typenod(rcvr))
|
||||||
this.Left.Name.Param.Ntype = this.Right
|
this.Left.Name.Param.Ntype = this.Right
|
||||||
in := structargs(method.Type.Params(), true)
|
in := structargs(method.Type.Params(), true)
|
||||||
out := structargs(method.Type.Results(), false)
|
out := structargs(method.Type.Results(), false)
|
||||||
@ -1772,7 +1772,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
|
|||||||
// Add a dummy padding argument after the
|
// Add a dummy padding argument after the
|
||||||
// receiver to make up the difference.
|
// receiver to make up the difference.
|
||||||
tpad := typArray(Types[TUINT8], Types[Tptr].Width-rcvr.Width)
|
tpad := typArray(Types[TUINT8], Types[Tptr].Width-rcvr.Width)
|
||||||
pad := Nod(ODCLFIELD, newname(Lookup(".pad")), typenod(tpad))
|
pad := Nod(ODCLFIELD, newname(lookup(".pad")), typenod(tpad))
|
||||||
l = append(l, pad)
|
l = append(l, pad)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1821,7 +1821,7 @@ func genwrapper(rcvr *Type, method *Field, newnam *Sym, iface int) {
|
|||||||
fn.Nbody.Append(n)
|
fn.Nbody.Append(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
dot := adddot(NodSym(OXDOT, this.Left, method.Sym))
|
dot := adddot(nodSym(OXDOT, this.Left, method.Sym))
|
||||||
|
|
||||||
// generate call
|
// generate call
|
||||||
// It's not possible to use a tail call when dynamic linking on ppc64le. The
|
// It's not possible to use a tail call when dynamic linking on ppc64le. The
|
||||||
@ -1886,7 +1886,7 @@ func hashmem(t *Type) *Node {
|
|||||||
n := newname(sym)
|
n := newname(sym)
|
||||||
n.Class = PFUNC
|
n.Class = PFUNC
|
||||||
tfn := Nod(OTFUNC, nil, nil)
|
tfn := Nod(OTFUNC, nil, nil)
|
||||||
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
|
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(ptrto(t))))
|
||||||
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
||||||
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
tfn.List.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
||||||
tfn.Rlist.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
tfn.Rlist.Append(Nod(ODCLFIELD, nil, typenod(Types[TUINTPTR])))
|
||||||
@ -1906,7 +1906,7 @@ func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase bool) *Field {
|
|||||||
path, ambig := dotpath(s, t, &m, ignorecase)
|
path, ambig := dotpath(s, t, &m, ignorecase)
|
||||||
if path == nil {
|
if path == nil {
|
||||||
if ambig {
|
if ambig {
|
||||||
Yyerror("%v.%v is ambiguous", t, s)
|
yyerror("%v.%v is ambiguous", t, s)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -1919,7 +1919,7 @@ func ifacelookdot(s *Sym, t *Type, followptr *bool, ignorecase bool) *Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if m.Type.Etype != TFUNC || m.Type.Recv() == nil {
|
if m.Type.Etype != TFUNC || m.Type.Recv() == nil {
|
||||||
Yyerror("%v.%v is a field, not a method", t, s)
|
yyerror("%v.%v is a field, not a method", t, s)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1986,7 +1986,7 @@ func implements(t, iface *Type, m, samename **Field, ptr *int) bool {
|
|||||||
|
|
||||||
if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) {
|
if rcvr.IsPtr() && !t0.IsPtr() && !followptr && !isifacemethod(tm.Type) {
|
||||||
if false && Debug['r'] != 0 {
|
if false && Debug['r'] != 0 {
|
||||||
Yyerror("interface pointer mismatch")
|
yyerror("interface pointer mismatch")
|
||||||
}
|
}
|
||||||
|
|
||||||
*m = im
|
*m = im
|
||||||
@ -2154,40 +2154,40 @@ var reservedimports = []string{
|
|||||||
|
|
||||||
func isbadimport(path string) bool {
|
func isbadimport(path string) bool {
|
||||||
if strings.Contains(path, "\x00") {
|
if strings.Contains(path, "\x00") {
|
||||||
Yyerror("import path contains NUL")
|
yyerror("import path contains NUL")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ri := range reservedimports {
|
for _, ri := range reservedimports {
|
||||||
if path == ri {
|
if path == ri {
|
||||||
Yyerror("import path %q is reserved and cannot be used", path)
|
yyerror("import path %q is reserved and cannot be used", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range path {
|
for _, r := range path {
|
||||||
if r == utf8.RuneError {
|
if r == utf8.RuneError {
|
||||||
Yyerror("import path contains invalid UTF-8 sequence: %q", path)
|
yyerror("import path contains invalid UTF-8 sequence: %q", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if r < 0x20 || r == 0x7f {
|
if r < 0x20 || r == 0x7f {
|
||||||
Yyerror("import path contains control character: %q", path)
|
yyerror("import path contains control character: %q", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if r == '\\' {
|
if r == '\\' {
|
||||||
Yyerror("import path contains backslash; use slash: %q", path)
|
yyerror("import path contains backslash; use slash: %q", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if unicode.IsSpace(r) {
|
if unicode.IsSpace(r) {
|
||||||
Yyerror("import path contains space character: %q", path)
|
yyerror("import path contains space character: %q", path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) {
|
if strings.ContainsRune("!\"#$%&'()*,:;<=>?[]^`{|}", r) {
|
||||||
Yyerror("import path contains invalid character '%c': %q", r, path)
|
yyerror("import path contains invalid character '%c': %q", r, path)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2233,8 +2233,8 @@ func isdirectiface(t *Type) bool {
|
|||||||
|
|
||||||
// itabType loads the _type field from a runtime.itab struct.
|
// itabType loads the _type field from a runtime.itab struct.
|
||||||
func itabType(itab *Node) *Node {
|
func itabType(itab *Node) *Node {
|
||||||
typ := NodSym(ODOTPTR, itab, nil)
|
typ := nodSym(ODOTPTR, itab, nil)
|
||||||
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.Bounded = true // guaranteed not to fault
|
||||||
@ -2245,13 +2245,13 @@ func itabType(itab *Node) *Node {
|
|||||||
// The concrete type must be known to have type t.
|
// The concrete type must be known to have type t.
|
||||||
// It follows the pointer if !isdirectiface(t).
|
// It follows the pointer if !isdirectiface(t).
|
||||||
func ifaceData(n *Node, t *Type) *Node {
|
func ifaceData(n *Node, t *Type) *Node {
|
||||||
ptr := NodSym(OIDATA, n, nil)
|
ptr := nodSym(OIDATA, n, nil)
|
||||||
if isdirectiface(t) {
|
if isdirectiface(t) {
|
||||||
ptr.Type = t
|
ptr.Type = t
|
||||||
ptr.Typecheck = 1
|
ptr.Typecheck = 1
|
||||||
return ptr
|
return ptr
|
||||||
}
|
}
|
||||||
ptr.Type = Ptrto(t)
|
ptr.Type = ptrto(t)
|
||||||
ptr.Bounded = true
|
ptr.Bounded = true
|
||||||
ptr.Typecheck = 1
|
ptr.Typecheck = 1
|
||||||
ind := Nod(OIND, ptr, nil)
|
ind := Nod(OIND, ptr, nil)
|
||||||
|
@ -68,7 +68,7 @@ func typecheckswitch(n *Node) {
|
|||||||
n.Left.Right = typecheck(n.Left.Right, Erv)
|
n.Left.Right = typecheck(n.Left.Right, Erv)
|
||||||
t = n.Left.Right.Type
|
t = n.Left.Right.Type
|
||||||
if t != nil && !t.IsInterface() {
|
if t != nil && !t.IsInterface() {
|
||||||
Yyerror("cannot type switch on non-interface value %L", n.Left.Right)
|
yyerror("cannot type switch on non-interface value %L", n.Left.Right)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// expression switch
|
// expression switch
|
||||||
@ -83,14 +83,14 @@ func typecheckswitch(n *Node) {
|
|||||||
if t != nil {
|
if t != nil {
|
||||||
switch {
|
switch {
|
||||||
case !okforeq[t.Etype]:
|
case !okforeq[t.Etype]:
|
||||||
Yyerror("cannot switch on %L", n.Left)
|
yyerror("cannot switch on %L", n.Left)
|
||||||
case t.IsSlice():
|
case t.IsSlice():
|
||||||
nilonly = "slice"
|
nilonly = "slice"
|
||||||
case t.IsArray() && !t.IsComparable():
|
case t.IsArray() && !t.IsComparable():
|
||||||
Yyerror("cannot switch on %L", n.Left)
|
yyerror("cannot switch on %L", n.Left)
|
||||||
case t.IsStruct():
|
case t.IsStruct():
|
||||||
if f := t.IncomparableField(); f != nil {
|
if f := t.IncomparableField(); f != nil {
|
||||||
Yyerror("cannot switch on %L (struct containing %v cannot be compared)", n.Left, f.Type)
|
yyerror("cannot switch on %L (struct containing %v cannot be compared)", n.Left, f.Type)
|
||||||
}
|
}
|
||||||
case t.Etype == TFUNC:
|
case t.Etype == TFUNC:
|
||||||
nilonly = "func"
|
nilonly = "func"
|
||||||
@ -109,7 +109,7 @@ func typecheckswitch(n *Node) {
|
|||||||
// default
|
// default
|
||||||
if def != nil {
|
if def != nil {
|
||||||
setlineno(ncase)
|
setlineno(ncase)
|
||||||
Yyerror("multiple defaults in switch (first at %v)", def.Line())
|
yyerror("multiple defaults in switch (first at %v)", def.Line())
|
||||||
} else {
|
} else {
|
||||||
def = ncase
|
def = ncase
|
||||||
}
|
}
|
||||||
@ -130,17 +130,17 @@ func typecheckswitch(n *Node) {
|
|||||||
n1 = ls[i1]
|
n1 = ls[i1]
|
||||||
switch {
|
switch {
|
||||||
case n1.Op == OTYPE:
|
case n1.Op == OTYPE:
|
||||||
Yyerror("type %v is not an expression", n1.Type)
|
yyerror("type %v is not an expression", n1.Type)
|
||||||
case n1.Type != nil && assignop(n1.Type, t, nil) == 0 && assignop(t, n1.Type, nil) == 0:
|
case n1.Type != nil && assignop(n1.Type, t, nil) == 0 && assignop(t, n1.Type, nil) == 0:
|
||||||
if n.Left != nil {
|
if n.Left != nil {
|
||||||
Yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
|
yyerror("invalid case %v in switch on %v (mismatched types %v and %v)", n1, n.Left, n1.Type, t)
|
||||||
} else {
|
} else {
|
||||||
Yyerror("invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type)
|
yyerror("invalid case %v in switch (mismatched types %v and bool)", n1, n1.Type)
|
||||||
}
|
}
|
||||||
case nilonly != "" && !isnil(n1):
|
case nilonly != "" && !isnil(n1):
|
||||||
Yyerror("invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
|
yyerror("invalid case %v in switch (can only compare %s %v to nil)", n1, nilonly, n.Left)
|
||||||
case t.IsInterface() && !n1.Type.IsInterface() && !n1.Type.IsComparable():
|
case t.IsInterface() && !n1.Type.IsInterface() && !n1.Type.IsComparable():
|
||||||
Yyerror("invalid case %L in switch (incomparable type)", n1)
|
yyerror("invalid case %L in switch (incomparable type)", n1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// type switch
|
// type switch
|
||||||
@ -151,21 +151,21 @@ func typecheckswitch(n *Node) {
|
|||||||
case n1.Op == OLITERAL && n1.Type.IsKind(TNIL):
|
case n1.Op == OLITERAL && n1.Type.IsKind(TNIL):
|
||||||
// case nil:
|
// case nil:
|
||||||
if niltype != nil {
|
if niltype != nil {
|
||||||
Yyerror("multiple nil cases in type switch (first at %v)", niltype.Line())
|
yyerror("multiple nil cases in type switch (first at %v)", niltype.Line())
|
||||||
} else {
|
} else {
|
||||||
niltype = ncase
|
niltype = ncase
|
||||||
}
|
}
|
||||||
case n1.Op != OTYPE && n1.Type != nil: // should this be ||?
|
case n1.Op != OTYPE && n1.Type != nil: // should this be ||?
|
||||||
Yyerror("%L is not a type", n1)
|
yyerror("%L is not a type", n1)
|
||||||
// reset to original type
|
// reset to original type
|
||||||
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 {
|
||||||
Yyerror("impossible type switch case: %L cannot have dynamic type %v"+
|
yyerror("impossible type switch case: %L cannot have dynamic type %v"+
|
||||||
" (missing %v method)", n.Left.Right, n1.Type, missing.Sym)
|
" (missing %v method)", n.Left.Right, n1.Type, missing.Sym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,7 +200,7 @@ func typecheckswitch(n *Node) {
|
|||||||
func walkswitch(sw *Node) {
|
func walkswitch(sw *Node) {
|
||||||
// convert switch {...} to switch true {...}
|
// convert switch {...} to switch true {...}
|
||||||
if sw.Left == nil {
|
if sw.Left == nil {
|
||||||
sw.Left = Nodbool(true)
|
sw.Left = nodbool(true)
|
||||||
sw.Left = typecheck(sw.Left, Erv)
|
sw.Left = typecheck(sw.Left, Erv)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +241,7 @@ func (s *exprSwitch) walk(sw *Node) {
|
|||||||
// convert the switch into OIF statements
|
// convert the switch into OIF statements
|
||||||
var cas []*Node
|
var cas []*Node
|
||||||
if s.kind == switchKindTrue || s.kind == switchKindFalse {
|
if s.kind == switchKindTrue || s.kind == switchKindFalse {
|
||||||
s.exprname = Nodbool(s.kind == switchKindTrue)
|
s.exprname = nodbool(s.kind == switchKindTrue)
|
||||||
} else if consttype(cond) >= 0 {
|
} else if consttype(cond) >= 0 {
|
||||||
// leave constants to enable dead code elimination (issue 9608)
|
// leave constants to enable dead code elimination (issue 9608)
|
||||||
s.exprname = cond
|
s.exprname = cond
|
||||||
@ -378,7 +378,7 @@ func casebody(sw *Node, typeswvar *Node) {
|
|||||||
case 0:
|
case 0:
|
||||||
// default
|
// default
|
||||||
if def != nil {
|
if def != nil {
|
||||||
Yyerror("more than one default case")
|
yyerror("more than one default case")
|
||||||
}
|
}
|
||||||
// reuse original default case
|
// reuse original default case
|
||||||
n.Right = jmp
|
n.Right = jmp
|
||||||
@ -454,12 +454,12 @@ func casebody(sw *Node, typeswvar *Node) {
|
|||||||
if last.Xoffset == n.Xoffset && last.Op == OXFALL {
|
if last.Xoffset == n.Xoffset && last.Op == OXFALL {
|
||||||
if typeswvar != nil {
|
if typeswvar != nil {
|
||||||
setlineno(last)
|
setlineno(last)
|
||||||
Yyerror("cannot fallthrough in type switch")
|
yyerror("cannot fallthrough in type switch")
|
||||||
}
|
}
|
||||||
|
|
||||||
if i+1 >= sw.List.Len() {
|
if i+1 >= sw.List.Len() {
|
||||||
setlineno(last)
|
setlineno(last)
|
||||||
Yyerror("cannot fallthrough final case in switch")
|
yyerror("cannot fallthrough final case in switch")
|
||||||
}
|
}
|
||||||
|
|
||||||
last.Op = OFALL
|
last.Op = OFALL
|
||||||
@ -609,7 +609,7 @@ func (s *exprSwitch) checkDupCases(cc []caseClause) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
setlineno(c.node)
|
setlineno(c.node)
|
||||||
Yyerror("duplicate case %v in switch\n\tprevious case at %v", prev.Left, prev.Line())
|
yyerror("duplicate case %v in switch\n\tprevious case at %v", prev.Left, prev.Line())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if c.node.List.Len() == 2 {
|
if c.node.List.Len() == 2 {
|
||||||
@ -623,7 +623,7 @@ func (s *exprSwitch) checkDupCases(cc []caseClause) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
setlineno(c.node)
|
setlineno(c.node)
|
||||||
Yyerror("duplicate case %v in switch\n\tprevious case at %v", prev.Left, prev.Line())
|
yyerror("duplicate case %v in switch\n\tprevious case at %v", prev.Left, prev.Line())
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -655,7 +655,7 @@ func (s *exprSwitch) checkDupCases(cc []caseClause) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
setlineno(c.node)
|
setlineno(c.node)
|
||||||
Yyerror("duplicate case %v in switch\n\tprevious case at %v", prev.Left, prev.Line())
|
yyerror("duplicate case %v in switch\n\tprevious case at %v", prev.Left, prev.Line())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -674,13 +674,13 @@ func (s *typeSwitch) walk(sw *Node) {
|
|||||||
}
|
}
|
||||||
if cond.Right == nil {
|
if cond.Right == nil {
|
||||||
setlineno(sw)
|
setlineno(sw)
|
||||||
Yyerror("type switch must have an assignment")
|
yyerror("type switch must have an assignment")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cond.Right = walkexpr(cond.Right, &sw.Ninit)
|
cond.Right = walkexpr(cond.Right, &sw.Ninit)
|
||||||
if !cond.Right.Type.IsInterface() {
|
if !cond.Right.Type.IsInterface() {
|
||||||
Yyerror("type switch must be on an interface")
|
yyerror("type switch must be on an interface")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -739,7 +739,7 @@ func (s *typeSwitch) walk(sw *Node) {
|
|||||||
typ = itabType(typ)
|
typ = itabType(typ)
|
||||||
}
|
}
|
||||||
// Load hash from type.
|
// Load hash from type.
|
||||||
h := NodSym(ODOTPTR, typ, nil)
|
h := nodSym(ODOTPTR, typ, nil)
|
||||||
h.Type = Types[TUINT32]
|
h.Type = Types[TUINT32]
|
||||||
h.Typecheck = 1
|
h.Typecheck = 1
|
||||||
h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
|
h.Xoffset = int64(2 * Widthptr) // offset of hash in runtime._type
|
||||||
|
@ -637,9 +637,9 @@ type Iter struct {
|
|||||||
s []*Field
|
s []*Field
|
||||||
}
|
}
|
||||||
|
|
||||||
// IterFields returns the first field or method in struct or interface type t
|
// iterFields returns the first field or method in struct or interface type t
|
||||||
// and an Iter value to continue iterating across the rest.
|
// and an Iter value to continue iterating across the rest.
|
||||||
func IterFields(t *Type) (*Field, Iter) {
|
func iterFields(t *Type) (*Field, Iter) {
|
||||||
return t.Fields().Iter()
|
return t.Fields().Iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,8 +978,8 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
|
|||||||
|
|
||||||
fallthrough
|
fallthrough
|
||||||
case TINTER:
|
case TINTER:
|
||||||
t1, ti := IterFields(t)
|
t1, ti := iterFields(t)
|
||||||
x1, xi := IterFields(x)
|
x1, xi := iterFields(x)
|
||||||
for ; t1 != nil && x1 != nil; t1, x1 = ti.Next(), xi.Next() {
|
for ; t1 != nil && x1 != nil; t1, x1 = ti.Next(), xi.Next() {
|
||||||
if t1.Embedded != x1.Embedded {
|
if t1.Embedded != x1.Embedded {
|
||||||
return cmpForNe(t1.Embedded < x1.Embedded)
|
return cmpForNe(t1.Embedded < x1.Embedded)
|
||||||
@ -1002,8 +1002,8 @@ func (t *Type) cmp(x *Type) ssa.Cmp {
|
|||||||
case TFUNC:
|
case TFUNC:
|
||||||
for _, f := range recvsParamsResults {
|
for _, f := range recvsParamsResults {
|
||||||
// Loop over fields in structs, ignoring argument names.
|
// Loop over fields in structs, ignoring argument names.
|
||||||
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)
|
||||||
@ -1152,7 +1152,7 @@ func (t *Type) ElemType() ssa.Type {
|
|||||||
return t.Elem()
|
return t.Elem()
|
||||||
}
|
}
|
||||||
func (t *Type) PtrTo() ssa.Type {
|
func (t *Type) PtrTo() ssa.Type {
|
||||||
return Ptrto(t)
|
return ptrto(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Type) NumFields() int {
|
func (t *Type) NumFields() int {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -103,18 +103,18 @@ func lexinit() {
|
|||||||
idealbool = typ(TBOOL)
|
idealbool = typ(TBOOL)
|
||||||
|
|
||||||
s := Pkglookup("true", builtinpkg)
|
s := Pkglookup("true", builtinpkg)
|
||||||
s.Def = Nodbool(true)
|
s.Def = nodbool(true)
|
||||||
s.Def.Sym = Lookup("true")
|
s.Def.Sym = lookup("true")
|
||||||
s.Def.Name = new(Name)
|
s.Def.Name = new(Name)
|
||||||
s.Def.Type = idealbool
|
s.Def.Type = idealbool
|
||||||
|
|
||||||
s = Pkglookup("false", builtinpkg)
|
s = Pkglookup("false", builtinpkg)
|
||||||
s.Def = Nodbool(false)
|
s.Def = nodbool(false)
|
||||||
s.Def.Sym = Lookup("false")
|
s.Def.Sym = lookup("false")
|
||||||
s.Def.Name = new(Name)
|
s.Def.Name = new(Name)
|
||||||
s.Def.Type = idealbool
|
s.Def.Type = idealbool
|
||||||
|
|
||||||
s = Lookup("_")
|
s = lookup("_")
|
||||||
s.Block = -100
|
s.Block = -100
|
||||||
s.Def = Nod(ONAME, nil, nil)
|
s.Def = Nod(ONAME, nil, nil)
|
||||||
s.Def.Sym = s
|
s.Def.Sym = s
|
||||||
@ -361,7 +361,7 @@ func makeErrorInterface() *Type {
|
|||||||
rcvr := typ(TSTRUCT)
|
rcvr := typ(TSTRUCT)
|
||||||
rcvr.StructType().Funarg = FunargRcvr
|
rcvr.StructType().Funarg = FunargRcvr
|
||||||
field := newField()
|
field := newField()
|
||||||
field.Type = Ptrto(typ(TSTRUCT))
|
field.Type = ptrto(typ(TSTRUCT))
|
||||||
rcvr.SetFields([]*Field{field})
|
rcvr.SetFields([]*Field{field})
|
||||||
|
|
||||||
in := typ(TSTRUCT)
|
in := typ(TSTRUCT)
|
||||||
@ -380,7 +380,7 @@ func makeErrorInterface() *Type {
|
|||||||
|
|
||||||
t := typ(TINTER)
|
t := typ(TINTER)
|
||||||
field = newField()
|
field = newField()
|
||||||
field.Sym = Lookup("Error")
|
field.Sym = lookup("Error")
|
||||||
field.Type = f
|
field.Type = f
|
||||||
t.SetFields([]*Field{field})
|
t.SetFields([]*Field{field})
|
||||||
|
|
||||||
@ -448,7 +448,7 @@ func finishUniverse() {
|
|||||||
if s.Def == nil || (s.Name == "any" && Debug['A'] == 0) {
|
if s.Def == nil || (s.Name == "any" && Debug['A'] == 0) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
s1 := Lookup(s.Name)
|
s1 := lookup(s.Name)
|
||||||
if s1.Def != nil {
|
if s1.Def != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -461,5 +461,5 @@ func finishUniverse() {
|
|||||||
nodfp.Type = Types[TINT32]
|
nodfp.Type = Types[TINT32]
|
||||||
nodfp.Xoffset = 0
|
nodfp.Xoffset = 0
|
||||||
nodfp.Class = PPARAM
|
nodfp.Class = PPARAM
|
||||||
nodfp.Sym = Lookup(".fp")
|
nodfp.Sym = lookup(".fp")
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ func unsafenmagic(nn *Node) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if args.Len() == 0 {
|
if args.Len() == 0 {
|
||||||
Yyerror("missing argument for %v", s)
|
yyerror("missing argument for %v", s)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ func unsafenmagic(nn *Node) *Node {
|
|||||||
case ODOT, ODOTPTR:
|
case ODOT, ODOTPTR:
|
||||||
break
|
break
|
||||||
case OCALLPART:
|
case OCALLPART:
|
||||||
Yyerror("invalid expression %v: argument is a method value", nn)
|
yyerror("invalid expression %v: argument is a method value", nn)
|
||||||
goto ret
|
goto ret
|
||||||
default:
|
default:
|
||||||
goto bad
|
goto bad
|
||||||
@ -74,7 +74,7 @@ func unsafenmagic(nn *Node) *Node {
|
|||||||
// but accessing f must not otherwise involve
|
// but accessing f must not otherwise involve
|
||||||
// indirection via embedded pointer types.
|
// indirection via embedded pointer types.
|
||||||
if r1.Left != base {
|
if r1.Left != base {
|
||||||
Yyerror("invalid expression %v: selector implies indirection of embedded %v", nn, r1.Left)
|
yyerror("invalid expression %v: selector implies indirection of embedded %v", nn, r1.Left)
|
||||||
goto ret
|
goto ret
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
@ -92,12 +92,12 @@ func unsafenmagic(nn *Node) *Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if args.Len() > 1 {
|
if args.Len() > 1 {
|
||||||
Yyerror("extra arguments for %v", s)
|
yyerror("extra arguments for %v", s)
|
||||||
}
|
}
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
Yyerror("invalid expression %v", nn)
|
yyerror("invalid expression %v", nn)
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
// any side effects disappear; ignore init
|
// any side effects disappear; ignore init
|
||||||
|
@ -16,7 +16,7 @@ func (n *Node) Line() string {
|
|||||||
|
|
||||||
var atExitFuncs []func()
|
var atExitFuncs []func()
|
||||||
|
|
||||||
func AtExit(f func()) {
|
func atExit(f func()) {
|
||||||
atExitFuncs = append(atExitFuncs, f)
|
atExitFuncs = append(atExitFuncs, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ func startProfile() {
|
|||||||
if err := pprof.StartCPUProfile(f); err != nil {
|
if err := pprof.StartCPUProfile(f); err != nil {
|
||||||
Fatalf("%v", err)
|
Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
AtExit(pprof.StopCPUProfile)
|
atExit(pprof.StopCPUProfile)
|
||||||
}
|
}
|
||||||
if memprofile != "" {
|
if memprofile != "" {
|
||||||
if memprofilerate != 0 {
|
if memprofilerate != 0 {
|
||||||
@ -54,7 +54,7 @@ func startProfile() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
Fatalf("%v", err)
|
Fatalf("%v", err)
|
||||||
}
|
}
|
||||||
AtExit(func() {
|
atExit(func() {
|
||||||
runtime.GC() // profile all outstanding allocations
|
runtime.GC() // profile all outstanding allocations
|
||||||
if err := pprof.WriteHeapProfile(f); err != nil {
|
if err := pprof.WriteHeapProfile(f); err != nil {
|
||||||
Fatalf("%v", err)
|
Fatalf("%v", err)
|
||||||
|
@ -50,11 +50,11 @@ func walk(fn *Node) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
lineno = defn.Left.Lineno
|
lineno = defn.Left.Lineno
|
||||||
Yyerror("%v declared and not used", ln.Sym)
|
yyerror("%v declared and not used", ln.Sym)
|
||||||
defn.Left.Used = true // suppress repeats
|
defn.Left.Used = true // suppress repeats
|
||||||
} else {
|
} else {
|
||||||
lineno = ln.Lineno
|
lineno = ln.Lineno
|
||||||
Yyerror("%v declared and not used", ln.Sym)
|
yyerror("%v declared and not used", ln.Sym)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ func adjustargs(n *Node, adjust int) {
|
|||||||
callfunc := n.Left
|
callfunc := n.Left
|
||||||
for _, arg = range callfunc.List.Slice() {
|
for _, arg = range callfunc.List.Slice() {
|
||||||
if arg.Op != OAS {
|
if arg.Op != OAS {
|
||||||
Yyerror("call arg not assignment")
|
yyerror("call arg not assignment")
|
||||||
}
|
}
|
||||||
lhs = arg.Left
|
lhs = arg.Left
|
||||||
if lhs.Op == ONAME {
|
if lhs.Op == ONAME {
|
||||||
@ -129,7 +129,7 @@ func adjustargs(n *Node, adjust int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if lhs.Op != OINDREG {
|
if lhs.Op != OINDREG {
|
||||||
Yyerror("call argument store does not use OINDREG")
|
yyerror("call argument store does not use OINDREG")
|
||||||
}
|
}
|
||||||
|
|
||||||
// can't really check this in machine-indep code.
|
// can't really check this in machine-indep code.
|
||||||
@ -156,9 +156,9 @@ func walkstmt(n *Node) *Node {
|
|||||||
switch n.Op {
|
switch n.Op {
|
||||||
default:
|
default:
|
||||||
if n.Op == ONAME {
|
if n.Op == ONAME {
|
||||||
Yyerror("%v is not a top level statement", n.Sym)
|
yyerror("%v is not a top level statement", n.Sym)
|
||||||
} else {
|
} else {
|
||||||
Yyerror("%v is not a top level statement", n.Op)
|
yyerror("%v is not a top level statement", n.Op)
|
||||||
}
|
}
|
||||||
Dump("nottop", n)
|
Dump("nottop", n)
|
||||||
|
|
||||||
@ -226,7 +226,7 @@ func walkstmt(n *Node) *Node {
|
|||||||
v := n.Left
|
v := n.Left
|
||||||
if v.Class == PAUTOHEAP {
|
if v.Class == PAUTOHEAP {
|
||||||
if compiling_runtime {
|
if compiling_runtime {
|
||||||
Yyerror("%v escapes to heap, not allowed in runtime.", v)
|
yyerror("%v escapes to heap, not allowed in runtime.", v)
|
||||||
}
|
}
|
||||||
if prealloc[v] == nil {
|
if prealloc[v] == nil {
|
||||||
prealloc[v] = callnew(v.Type)
|
prealloc[v] = callnew(v.Type)
|
||||||
@ -241,7 +241,7 @@ func walkstmt(n *Node) *Node {
|
|||||||
walkstmtlist(n.List.Slice())
|
walkstmtlist(n.List.Slice())
|
||||||
|
|
||||||
case OXCASE:
|
case OXCASE:
|
||||||
Yyerror("case statement out of place")
|
yyerror("case statement out of place")
|
||||||
n.Op = OCASE
|
n.Op = OCASE
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
@ -361,7 +361,7 @@ func walkstmt(n *Node) *Node {
|
|||||||
walkrange(n)
|
walkrange(n)
|
||||||
|
|
||||||
case OXFALL:
|
case OXFALL:
|
||||||
Yyerror("fallthrough statement out of place")
|
yyerror("fallthrough statement out of place")
|
||||||
n.Op = OFALL
|
n.Op = OFALL
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,7 +907,7 @@ opswitch:
|
|||||||
|
|
||||||
// don't generate a = *var if a is _
|
// don't generate a = *var if a is _
|
||||||
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_.NonNil = true // mapaccess always returns a non-nil pointer
|
||||||
n.List.SetIndex(0, var_)
|
n.List.SetIndex(0, var_)
|
||||||
@ -980,7 +980,7 @@ opswitch:
|
|||||||
tab := Nod(OITAB, from, nil)
|
tab := Nod(OITAB, from, nil)
|
||||||
if fromKind == 'E' {
|
if fromKind == 'E' {
|
||||||
typ := Nod(OCONVNOP, typename(t), nil)
|
typ := Nod(OCONVNOP, typename(t), nil)
|
||||||
typ.Type = Ptrto(Types[TUINTPTR])
|
typ.Type = ptrto(Types[TUINTPTR])
|
||||||
fast = Nod(OEQ, tab, typ)
|
fast = Nod(OEQ, tab, typ)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -1253,7 +1253,7 @@ opswitch:
|
|||||||
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.Bounded = bounded(r, int64(len(n.Left.Val().U.(string))))
|
||||||
@ -1262,7 +1262,7 @@ opswitch:
|
|||||||
}
|
}
|
||||||
if smallintconst(n.Right) {
|
if smallintconst(n.Right) {
|
||||||
if !n.Bounded {
|
if !n.Bounded {
|
||||||
Yyerror("index out of bounds")
|
yyerror("index out of bounds")
|
||||||
} else {
|
} else {
|
||||||
// replace "abc"[1] with 'b'.
|
// replace "abc"[1] with 'b'.
|
||||||
// delayed until now because "abc"[1] is not
|
// delayed until now because "abc"[1] is not
|
||||||
@ -1277,7 +1277,7 @@ opswitch:
|
|||||||
|
|
||||||
if Isconst(n.Right, CTINT) {
|
if Isconst(n.Right, CTINT) {
|
||||||
if n.Right.Val().U.(*Mpint).CmpInt64(0) < 0 || n.Right.Val().U.(*Mpint).Cmp(Maxintval[TINT]) > 0 {
|
if n.Right.Val().U.(*Mpint).CmpInt64(0) < 0 || n.Right.Val().U.(*Mpint).Cmp(Maxintval[TINT]) > 0 {
|
||||||
Yyerror("index out of bounds")
|
yyerror("index out of bounds")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1313,11 +1313,11 @@ opswitch:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/hashmap.go:maxZero
|
if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/hashmap.go:maxZero
|
||||||
n = mkcall1(mapfn(p, t), Ptrto(t.Val()), init, typename(t), n.Left, key)
|
n = mkcall1(mapfn(p, t), ptrto(t.Val()), init, typename(t), n.Left, key)
|
||||||
} else {
|
} else {
|
||||||
p = "mapaccess1_fat"
|
p = "mapaccess1_fat"
|
||||||
z := zeroaddr(w)
|
z := zeroaddr(w)
|
||||||
n = mkcall1(mapfn(p, t), Ptrto(t.Val()), init, typename(t), n.Left, key, z)
|
n = mkcall1(mapfn(p, t), ptrto(t.Val()), init, typename(t), n.Left, key, z)
|
||||||
}
|
}
|
||||||
n.NonNil = true // mapaccess always returns a non-nil pointer
|
n.NonNil = true // mapaccess always returns a non-nil pointer
|
||||||
n = Nod(OIND, n, nil)
|
n = Nod(OIND, n, nil)
|
||||||
@ -1758,7 +1758,7 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
|
|||||||
var nln, nrn Nodes
|
var nln, nrn Nodes
|
||||||
nln.Set(nl)
|
nln.Set(nl)
|
||||||
nrn.Set(nr)
|
nrn.Set(nr)
|
||||||
Yyerror("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), Curfn.Func.Nname.Sym.Name)
|
yyerror("error in shape across %+v %v %+v / %d %d [%s]", nln, op, nrn, len(nl), len(nr), Curfn.Func.Nname.Sym.Name)
|
||||||
}
|
}
|
||||||
return nn
|
return nn
|
||||||
}
|
}
|
||||||
@ -1785,7 +1785,7 @@ func fncall(l *Node, rt *Type) bool {
|
|||||||
// a expression list. called in
|
// a expression list. called in
|
||||||
// expr-list = func()
|
// expr-list = func()
|
||||||
func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node {
|
func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node {
|
||||||
r, saver := IterFields(nr)
|
r, saver := iterFields(nr)
|
||||||
|
|
||||||
var nn, mm []*Node
|
var nn, mm []*Node
|
||||||
var ullmanOverflow bool
|
var ullmanOverflow bool
|
||||||
@ -1825,7 +1825,7 @@ func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if i < nl.Len() || r != nil {
|
if i < nl.Len() || r != nil {
|
||||||
Yyerror("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
|
yyerror("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
|
||||||
}
|
}
|
||||||
|
|
||||||
if ullmanOverflow {
|
if ullmanOverflow {
|
||||||
@ -1874,7 +1874,7 @@ func dumptypes(nl *Type, what string) string {
|
|||||||
if s != "" {
|
if s != "" {
|
||||||
s += ", "
|
s += ", "
|
||||||
}
|
}
|
||||||
s += Fldconv(l, 0)
|
s += fldconv(l, 0)
|
||||||
}
|
}
|
||||||
if s == "" {
|
if s == "" {
|
||||||
s = fmt.Sprintf("[no arguments %s]", what)
|
s = fmt.Sprintf("[no arguments %s]", what)
|
||||||
@ -1902,7 +1902,7 @@ func dumpnodetypes(l []*Node, what string) string {
|
|||||||
// func(expr-list)
|
// func(expr-list)
|
||||||
func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, init *Nodes) []*Node {
|
func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, init *Nodes) []*Node {
|
||||||
lr0 := lr
|
lr0 := lr
|
||||||
l, savel := IterFields(nl)
|
l, savel := iterFields(nl)
|
||||||
var r *Node
|
var r *Node
|
||||||
if len(lr) > 0 {
|
if len(lr) > 0 {
|
||||||
r = lr[0]
|
r = lr[0]
|
||||||
@ -1937,7 +1937,7 @@ func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, ini
|
|||||||
init.Append(a)
|
init.Append(a)
|
||||||
lr = alist
|
lr = alist
|
||||||
r = lr[0]
|
r = lr[0]
|
||||||
l, savel = IterFields(nl)
|
l, savel = iterFields(nl)
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
@ -1946,7 +1946,7 @@ func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, ini
|
|||||||
ll := savel.Next()
|
ll := savel.Next()
|
||||||
|
|
||||||
if ll != nil {
|
if ll != nil {
|
||||||
Yyerror("... must be last argument")
|
yyerror("... must be last argument")
|
||||||
}
|
}
|
||||||
|
|
||||||
// special case --
|
// special case --
|
||||||
@ -1973,9 +1973,9 @@ func ascompatte(op Op, call *Node, isddd bool, nl *Type, lr []*Node, fp int, ini
|
|||||||
l1 := dumptypes(nl, "expected")
|
l1 := dumptypes(nl, "expected")
|
||||||
l2 := dumpnodetypes(lr0, "given")
|
l2 := dumpnodetypes(lr0, "given")
|
||||||
if l != nil {
|
if l != nil {
|
||||||
Yyerror("not enough arguments to %v\n\t%s\n\t%s", op, l1, l2)
|
yyerror("not enough arguments to %v\n\t%s\n\t%s", op, l1, l2)
|
||||||
} else {
|
} else {
|
||||||
Yyerror("too many arguments to %v\n\t%s\n\t%s", op, l1, l2)
|
yyerror("too many arguments to %v\n\t%s\n\t%s", op, l1, l2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2118,7 +2118,7 @@ func callnew(t *Type) *Node {
|
|||||||
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.NonNil = true
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
@ -2793,7 +2793,7 @@ func addstr(n *Node, init *Nodes) *Node {
|
|||||||
c := n.List.Len()
|
c := n.List.Len()
|
||||||
|
|
||||||
if c < 2 {
|
if c < 2 {
|
||||||
Yyerror("addstr count %d too small", c)
|
yyerror("addstr count %d too small", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := nodnil()
|
buf := nodnil()
|
||||||
@ -3140,8 +3140,8 @@ func eqfor(t *Type, needsize *int) *Node {
|
|||||||
n := newname(sym)
|
n := newname(sym)
|
||||||
n.Class = PFUNC
|
n.Class = PFUNC
|
||||||
ntype := Nod(OTFUNC, nil, nil)
|
ntype := Nod(OTFUNC, nil, nil)
|
||||||
ntype.List.Append(Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
|
ntype.List.Append(Nod(ODCLFIELD, nil, typenod(ptrto(t))))
|
||||||
ntype.List.Append(Nod(ODCLFIELD, nil, typenod(Ptrto(t))))
|
ntype.List.Append(Nod(ODCLFIELD, nil, typenod(ptrto(t))))
|
||||||
ntype.Rlist.Append(Nod(ODCLFIELD, nil, typenod(Types[TBOOL])))
|
ntype.Rlist.Append(Nod(ODCLFIELD, nil, typenod(Types[TBOOL])))
|
||||||
ntype = typecheck(ntype, Etype)
|
ntype = typecheck(ntype, Etype)
|
||||||
n.Type = ntype.Type
|
n.Type = ntype.Type
|
||||||
@ -3186,11 +3186,11 @@ func walkcompare(n *Node, init *Nodes) *Node {
|
|||||||
tab := Nod(OITAB, l, nil)
|
tab := Nod(OITAB, l, nil)
|
||||||
rtyp := typename(r.Type)
|
rtyp := typename(r.Type)
|
||||||
if l.Type.IsEmptyInterface() {
|
if l.Type.IsEmptyInterface() {
|
||||||
tab.Type = Ptrto(Types[TUINT8])
|
tab.Type = ptrto(Types[TUINT8])
|
||||||
tab.Typecheck = 1
|
tab.Typecheck = 1
|
||||||
eqtype = Nod(eq, tab, rtyp)
|
eqtype = Nod(eq, tab, rtyp)
|
||||||
} else {
|
} else {
|
||||||
nonnil := Nod(Brcom(eq), nodnil(), tab)
|
nonnil := Nod(brcom(eq), nodnil(), tab)
|
||||||
match := Nod(eq, itabType(tab), rtyp)
|
match := Nod(eq, itabType(tab), rtyp)
|
||||||
eqtype = Nod(andor, nonnil, match)
|
eqtype = Nod(andor, nonnil, match)
|
||||||
}
|
}
|
||||||
@ -3233,13 +3233,13 @@ func walkcompare(n *Node, init *Nodes) *Node {
|
|||||||
// Chose not to inline. Call equality function directly.
|
// Chose not to inline. Call equality function directly.
|
||||||
if !inline {
|
if !inline {
|
||||||
// eq algs take pointers
|
// eq algs take pointers
|
||||||
pl := temp(Ptrto(t))
|
pl := temp(ptrto(t))
|
||||||
al := Nod(OAS, pl, Nod(OADDR, cmpl, nil))
|
al := Nod(OAS, pl, Nod(OADDR, cmpl, nil))
|
||||||
al.Right.Etype = 1 // addr does not escape
|
al.Right.Etype = 1 // addr does not escape
|
||||||
al = typecheck(al, Etop)
|
al = typecheck(al, Etop)
|
||||||
init.Append(al)
|
init.Append(al)
|
||||||
|
|
||||||
pr := temp(Ptrto(t))
|
pr := temp(ptrto(t))
|
||||||
ar := Nod(OAS, pr, Nod(OADDR, cmpr, nil))
|
ar := Nod(OAS, pr, Nod(OADDR, cmpr, nil))
|
||||||
ar.Right.Etype = 1 // addr does not escape
|
ar.Right.Etype = 1 // addr does not escape
|
||||||
ar = typecheck(ar, Etop)
|
ar = typecheck(ar, Etop)
|
||||||
@ -3283,8 +3283,8 @@ func walkcompare(n *Node, init *Nodes) *Node {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
compare(
|
compare(
|
||||||
NodSym(OXDOT, cmpl, sym),
|
nodSym(OXDOT, cmpl, sym),
|
||||||
NodSym(OXDOT, cmpr, sym),
|
nodSym(OXDOT, cmpr, sym),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3296,7 +3296,7 @@ func walkcompare(n *Node, init *Nodes) *Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if expr == nil {
|
if expr == nil {
|
||||||
expr = Nodbool(n.Op == OEQ)
|
expr = nodbool(n.Op == OEQ)
|
||||||
}
|
}
|
||||||
n = finishcompare(n, expr, init)
|
n = finishcompare(n, expr, init)
|
||||||
return n
|
return n
|
||||||
@ -3448,9 +3448,9 @@ func walkinrange(n *Node, init *Nodes) *Node {
|
|||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if i&1 == 0 {
|
if i&1 == 0 {
|
||||||
a, opl, b = b, Brrev(opl), a
|
a, opl, b = b, brrev(opl), a
|
||||||
} else {
|
} else {
|
||||||
x, opr, c = c, Brrev(opr), x
|
x, opr, c = c, brrev(opr), x
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3459,8 +3459,8 @@ func walkinrange(n *Node, init *Nodes) *Node {
|
|||||||
// Henceforth assume &&.
|
// Henceforth assume &&.
|
||||||
negateResult := n.Op == OOROR
|
negateResult := n.Op == OOROR
|
||||||
if negateResult {
|
if negateResult {
|
||||||
opl = Brcom(opl)
|
opl = brcom(opl)
|
||||||
opr = Brcom(opr)
|
opr = brcom(opr)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmpdir := func(o Op) int {
|
cmpdir := func(o Op) int {
|
||||||
@ -3484,7 +3484,7 @@ func walkinrange(n *Node, init *Nodes) *Node {
|
|||||||
// Switch and reverse ops and rename constants,
|
// Switch and reverse ops and rename constants,
|
||||||
// to make it look like a ≤ b && b < c.
|
// to make it look like a ≤ b && b < c.
|
||||||
a, c = c, a
|
a, c = c, a
|
||||||
opl, opr = Brrev(opr), Brrev(opl)
|
opl, opr = brrev(opr), brrev(opl)
|
||||||
}
|
}
|
||||||
|
|
||||||
// We must ensure that c-a is non-negative.
|
// We must ensure that c-a is non-negative.
|
||||||
@ -3525,7 +3525,7 @@ func walkinrange(n *Node, init *Nodes) *Node {
|
|||||||
rhs := nodintconst(bound)
|
rhs := nodintconst(bound)
|
||||||
if negateResult {
|
if negateResult {
|
||||||
// Negate top level.
|
// Negate top level.
|
||||||
opr = Brcom(opr)
|
opr = brcom(opr)
|
||||||
}
|
}
|
||||||
cmp := Nod(opr, lhs, rhs)
|
cmp := Nod(opr, lhs, rhs)
|
||||||
cmp.Lineno = n.Lineno
|
cmp.Lineno = n.Lineno
|
||||||
@ -4006,10 +4006,10 @@ func usefield(n *Node) {
|
|||||||
outer = outer.Elem()
|
outer = outer.Elem()
|
||||||
}
|
}
|
||||||
if outer.Sym == nil {
|
if outer.Sym == nil {
|
||||||
Yyerror("tracked field must be in named struct type")
|
yyerror("tracked field must be in named struct type")
|
||||||
}
|
}
|
||||||
if !exportname(field.Sym.Name) {
|
if !exportname(field.Sym.Name) {
|
||||||
Yyerror("tracked field must be exported (upper case)")
|
yyerror("tracked field must be exported (upper case)")
|
||||||
}
|
}
|
||||||
|
|
||||||
sym := tracksym(outer, field)
|
sym := tracksym(outer, field)
|
||||||
@ -4148,7 +4148,7 @@ func walkprintfunc(n *Node, init *Nodes) *Node {
|
|||||||
for _, n1 := range n.List.Slice() {
|
for _, n1 := range n.List.Slice() {
|
||||||
buf = fmt.Sprintf("a%d", num)
|
buf = fmt.Sprintf("a%d", num)
|
||||||
num++
|
num++
|
||||||
a = Nod(ODCLFIELD, newname(Lookup(buf)), typenod(n1.Type))
|
a = Nod(ODCLFIELD, newname(lookup(buf)), typenod(n1.Type))
|
||||||
t.List.Append(a)
|
t.List.Append(a)
|
||||||
printargs = append(printargs, a.Left)
|
printargs = append(printargs, a.Left)
|
||||||
}
|
}
|
||||||
@ -4156,7 +4156,7 @@ func walkprintfunc(n *Node, init *Nodes) *Node {
|
|||||||
fn := Nod(ODCLFUNC, nil, nil)
|
fn := Nod(ODCLFUNC, nil, nil)
|
||||||
walkprintfunc_prgen++
|
walkprintfunc_prgen++
|
||||||
buf = fmt.Sprintf("print·%d", walkprintfunc_prgen)
|
buf = fmt.Sprintf("print·%d", walkprintfunc_prgen)
|
||||||
fn.Func.Nname = newname(Lookup(buf))
|
fn.Func.Nname = newname(lookup(buf))
|
||||||
fn.Func.Nname.Name.Defn = fn
|
fn.Func.Nname.Name.Defn = fn
|
||||||
fn.Func.Nname.Name.Param.Ntype = t
|
fn.Func.Nname.Name.Param.Ntype = t
|
||||||
declare(fn.Func.Nname, PFUNC)
|
declare(fn.Func.Nname, PFUNC)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user