Commit 49cce1a6 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: add OSLICELIT

Does not pass toolstash -cmp due to changed export data,
but the cmd/go binary (which doesn't contain export data)
is bit-for-bit identical.

Change-Id: I6b12f9de18cf7da528e9207dccbf8f08c969f142
Reviewed-on: https://go-review.googlesource.com/26753
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarDavid Crawshaw <crawshaw@golang.org>
parent 41e1c420
...@@ -1258,7 +1258,7 @@ func (p *exporter) expr(n *Node) { ...@@ -1258,7 +1258,7 @@ func (p *exporter) expr(n *Node) {
p.typ(n.Type) p.typ(n.Type)
p.elemList(n.List) // special handling of field names p.elemList(n.List) // special handling of field names
case OARRAYLIT, OMAPLIT: case OARRAYLIT, OSLICELIT, OMAPLIT:
p.op(OCOMPLIT) p.op(OCOMPLIT)
p.typ(n.Type) p.typ(n.Type)
p.exprList(n.List) p.exprList(n.List)
......
...@@ -897,7 +897,7 @@ func (p *importer) node() *Node { ...@@ -897,7 +897,7 @@ func (p *importer) node() *Node {
n.List.Set(p.elemList()) // special handling of field names n.List.Set(p.elemList()) // special handling of field names
return n return n
// case OARRAYLIT, OMAPLIT: // case OARRAYLIT, OSLICELIT, OMAPLIT:
// unreachable - mapped to case OCOMPLIT below by exporter // unreachable - mapped to case OCOMPLIT below by exporter
case OCOMPLIT: case OCOMPLIT:
......
...@@ -863,15 +863,17 @@ func esc(e *EscState, n *Node, up *Node) { ...@@ -863,15 +863,17 @@ func esc(e *EscState, n *Node, up *Node) {
escassignNilWhy(e, n, n.Left, "interface-converted") escassignNilWhy(e, n, n.Left, "interface-converted")
case OARRAYLIT: case OARRAYLIT:
why := "array literal element" // Link values to array
if n.Type.IsSlice() { for _, n5 := range n.List.Slice() {
// Slice itself is not leaked until proven otherwise escassign(e, n, n5.Right, e.stepAssign(nil, n, n5.Right, "array literal element"))
e.track(n)
why = "slice literal element"
} }
// Link values to array/slice
case OSLICELIT:
// Slice is not leaked until proven otherwise
e.track(n)
// Link values to slice
for _, n5 := range n.List.Slice() { for _, n5 := range n.List.Slice() {
escassign(e, n, n5.Right, e.stepAssign(nil, n, n5.Right, why)) escassign(e, n, n5.Right, e.stepAssign(nil, n, n5.Right, "slice literal element"))
} }
// Link values to struct. // Link values to struct.
...@@ -1015,6 +1017,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) { ...@@ -1015,6 +1017,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
Fatalf("escassign: unexpected dst") Fatalf("escassign: unexpected dst")
case OARRAYLIT, case OARRAYLIT,
OSLICELIT,
OCLOSURE, OCLOSURE,
OCONV, OCONV,
OCONVIFACE, OCONVIFACE,
...@@ -1071,6 +1074,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) { ...@@ -1071,6 +1074,7 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
ODDDARG, ODDDARG,
OPTRLIT, OPTRLIT,
OARRAYLIT, OARRAYLIT,
OSLICELIT,
OMAPLIT, OMAPLIT,
OSTRUCTLIT, OSTRUCTLIT,
OMAKECHAN, OMAKECHAN,
...@@ -1587,6 +1591,7 @@ func esccall(e *EscState, n *Node, up *Node) { ...@@ -1587,6 +1591,7 @@ func esccall(e *EscState, n *Node, up *Node) {
OCLOSURE, OCLOSURE,
ODDDARG, ODDDARG,
OARRAYLIT, OARRAYLIT,
OSLICELIT,
OPTRLIT, OPTRLIT,
OSTRUCTLIT: OSTRUCTLIT:
a.Noescape = true a.Noescape = true
...@@ -1881,10 +1886,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep, ...@@ -1881,10 +1886,7 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
// similar to a slice arraylit and its args. // similar to a slice arraylit and its args.
level = level.dec() level = level.dec()
case OARRAYLIT: case OSLICELIT:
if src.Type.IsArray() {
break
}
for _, n1 := range src.List.Slice() { for _, n1 := range src.List.Slice() {
escwalk(e, level.dec(), dst, n1.Right, e.stepWalk(dst, n1.Right, "slice-literal-element", step)) escwalk(e, level.dec(), dst, n1.Right, e.stepWalk(dst, n1.Right, "slice-literal-element", step))
} }
......
...@@ -182,6 +182,7 @@ func reexportdep(n *Node) { ...@@ -182,6 +182,7 @@ func reexportdep(n *Node) {
ODOTTYPE2, ODOTTYPE2,
OSTRUCTLIT, OSTRUCTLIT,
OARRAYLIT, OARRAYLIT,
OSLICELIT,
OPTRLIT, OPTRLIT,
OMAKEMAP, OMAKEMAP,
OMAKESLICE, OMAKESLICE,
......
...@@ -931,6 +931,7 @@ var opprec = []int{ ...@@ -931,6 +931,7 @@ var opprec = []int{
OAPPEND: 8, OAPPEND: 8,
OARRAYBYTESTR: 8, OARRAYBYTESTR: 8,
OARRAYLIT: 8, OARRAYLIT: 8,
OSLICELIT: 8,
OARRAYRUNESTR: 8, OARRAYRUNESTR: 8,
OCALLFUNC: 8, OCALLFUNC: 8,
OCALLINTER: 8, OCALLINTER: 8,
...@@ -1172,7 +1173,7 @@ func (p *printer) exprfmt(n *Node, prec int) *printer { ...@@ -1172,7 +1173,7 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
case OPTRLIT: case OPTRLIT:
return p.f("&%v", n.Left) return p.f("&%v", n.Left)
case OSTRUCTLIT, OARRAYLIT, OMAPLIT: case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
if fmtmode == FErr { if fmtmode == FErr {
return p.f("%v literal", n.Type) return p.f("%v literal", n.Type)
} }
......
...@@ -48,6 +48,7 @@ var opnames = []string{ ...@@ -48,6 +48,7 @@ var opnames = []string{
OMAPLIT: "MAPLIT", OMAPLIT: "MAPLIT",
OSTRUCTLIT: "STRUCTLIT", OSTRUCTLIT: "STRUCTLIT",
OARRAYLIT: "ARRAYLIT", OARRAYLIT: "ARRAYLIT",
OSLICELIT: "SLICELIT",
OPTRLIT: "PTRLIT", OPTRLIT: "PTRLIT",
OCONV: "CONV", OCONV: "CONV",
OCONVIFACE: "CONVIFACE", OCONVIFACE: "CONVIFACE",
......
...@@ -1160,7 +1160,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node { ...@@ -1160,7 +1160,7 @@ func orderexpr(n *Node, order *Order, lhs *Node) *Node {
prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type prealloc[n] = ordertemp(Types[TUINT8], order, false) // walk will fill in correct type
} }
case OARRAYLIT, OCALLPART: case OARRAYLIT, OSLICELIT, OCALLPART:
n.Left = orderexpr(n.Left, order, nil) n.Left = orderexpr(n.Left, order, nil)
n.Right = orderexpr(n.Right, order, nil) n.Right = orderexpr(n.Right, order, nil)
orderexprlist(n.List, order) orderexprlist(n.List, order)
......
...@@ -368,6 +368,7 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) { ...@@ -368,6 +368,7 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
OCLOSURE, // lowered to PTRLIT OCLOSURE, // lowered to PTRLIT
ORANGE, // lowered to ordinary for loop ORANGE, // lowered to ordinary for loop
OARRAYLIT, // lowered to assignments OARRAYLIT, // lowered to assignments
OSLICELIT,
OMAPLIT, OMAPLIT,
OSTRUCTLIT, OSTRUCTLIT,
OAS2, OAS2,
......
...@@ -316,33 +316,26 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool { ...@@ -316,33 +316,26 @@ func staticcopy(l *Node, r *Node, out *[]*Node) bool {
case OPTRLIT: case OPTRLIT:
switch r.Left.Op { switch r.Left.Op {
//dump("not static addr", r); case OARRAYLIT, OSLICELIT, OSTRUCTLIT, OMAPLIT:
default:
break
// copy pointer // copy pointer
case OARRAYLIT, OSTRUCTLIT, OMAPLIT:
gdata(l, Nod(OADDR, inittemps[r], nil), int(l.Type.Width)) gdata(l, Nod(OADDR, inittemps[r], nil), int(l.Type.Width))
return true return true
} }
case OARRAYLIT: case OSLICELIT:
if r.Type.IsSlice() { // copy slice
// copy slice a := inittemps[r]
a := inittemps[r]
n := *l n := *l
n.Xoffset = l.Xoffset + int64(Array_array) n.Xoffset = l.Xoffset + int64(Array_array)
gdata(&n, Nod(OADDR, a, nil), Widthptr) gdata(&n, Nod(OADDR, a, nil), Widthptr)
n.Xoffset = l.Xoffset + int64(Array_nel) n.Xoffset = l.Xoffset + int64(Array_nel)
gdata(&n, r.Right, Widthint) gdata(&n, r.Right, Widthint)
n.Xoffset = l.Xoffset + int64(Array_cap) n.Xoffset = l.Xoffset + int64(Array_cap)
gdata(&n, r.Right, Widthint) gdata(&n, r.Right, Widthint)
return true return true
}
fallthrough case OARRAYLIT, OSTRUCTLIT:
case OSTRUCTLIT:
p := initplans[r] p := initplans[r]
n := *l n := *l
...@@ -405,7 +398,7 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool { ...@@ -405,7 +398,7 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool {
case OPTRLIT: case OPTRLIT:
switch r.Left.Op { switch r.Left.Op {
case OARRAYLIT, OMAPLIT, OSTRUCTLIT: case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT:
// Init pointer. // Init pointer.
a := staticname(r.Left.Type, 1) a := staticname(r.Left.Type, 1)
...@@ -427,28 +420,26 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool { ...@@ -427,28 +420,26 @@ func staticassign(l *Node, r *Node, out *[]*Node) bool {
return true return true
} }
case OARRAYLIT: case OSLICELIT:
initplan(r) initplan(r)
if r.Type.IsSlice() { // Init slice.
// Init slice. bound := r.Right.Int64()
bound := r.Right.Int64() ta := typArray(r.Type.Elem(), bound)
ta := typArray(r.Type.Elem(), bound) a := staticname(ta, 1)
a := staticname(ta, 1) inittemps[r] = a
inittemps[r] = a n := *l
n := *l n.Xoffset = l.Xoffset + int64(Array_array)
n.Xoffset = l.Xoffset + int64(Array_array) gdata(&n, Nod(OADDR, a, nil), Widthptr)
gdata(&n, Nod(OADDR, a, nil), Widthptr) n.Xoffset = l.Xoffset + int64(Array_nel)
n.Xoffset = l.Xoffset + int64(Array_nel) gdata(&n, r.Right, Widthint)
gdata(&n, r.Right, Widthint) n.Xoffset = l.Xoffset + int64(Array_cap)
n.Xoffset = l.Xoffset + int64(Array_cap) gdata(&n, r.Right, Widthint)
gdata(&n, r.Right, Widthint)
// Fall through to init underlying array.
// Fall through to init underlying array. l = a
l = a
}
fallthrough fallthrough
case OSTRUCTLIT: case OARRAYLIT, OSTRUCTLIT:
initplan(r) initplan(r)
p := initplans[r] p := initplans[r]
...@@ -543,12 +534,12 @@ func getdyn(n *Node, top bool) initGenType { ...@@ -543,12 +534,12 @@ func getdyn(n *Node, top bool) initGenType {
} }
return initDynamic return initDynamic
case OARRAYLIT: case OSLICELIT:
if !top && n.Type.IsSlice() { if !top {
return initDynamic return initDynamic
} }
case OSTRUCTLIT: case OARRAYLIT, OSTRUCTLIT:
} }
var mode initGenType var mode initGenType
...@@ -565,30 +556,27 @@ func getdyn(n *Node, top bool) initGenType { ...@@ -565,30 +556,27 @@ func getdyn(n *Node, top bool) initGenType {
// isStaticCompositeLiteral reports whether n is a compile-time constant. // isStaticCompositeLiteral reports whether n is a compile-time constant.
func isStaticCompositeLiteral(n *Node) bool { func isStaticCompositeLiteral(n *Node) bool {
switch n.Op { switch n.Op {
case OARRAYLIT: case OSLICELIT:
if n.Type.IsSlice() { return false
return false case OARRAYLIT, OSTRUCTLIT:
for _, r := range n.List.Slice() {
if r.Op != OKEY {
Fatalf("isStaticCompositeLiteral: rhs not OKEY: %v", r)
}
index := r.Left
if n.Op == OARRAYLIT && index.Op != OLITERAL {
return false
}
value := r.Right
if !isStaticCompositeLiteral(value) {
return false
}
} }
case OSTRUCTLIT: return true
case OLITERAL: case OLITERAL:
return true return true
default:
return false
} }
for _, r := range n.List.Slice() { return false
if r.Op != OKEY {
Fatalf("isStaticCompositeLiteral: rhs not OKEY: %v", r)
}
index := r.Left
if n.Op == OARRAYLIT && index.Op != OLITERAL {
return false
}
value := r.Right
if !isStaticCompositeLiteral(value) {
return false
}
}
return true
} }
func structlit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) { func structlit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) {
...@@ -600,20 +588,19 @@ func structlit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) { ...@@ -600,20 +588,19 @@ func structlit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) {
value := r.Right value := r.Right
switch value.Op { switch value.Op {
case OARRAYLIT: case OSLICELIT:
if value.Type.IsSlice() { if pass == 1 && ctxt != 0 {
if pass == 1 && ctxt != 0 { a := NodSym(ODOT, var_, index.Sym)
a := NodSym(ODOT, var_, index.Sym) slicelit(ctxt, value, a, init)
slicelit(ctxt, value, a, init) } else if pass == 2 && ctxt == 0 {
} else if pass == 2 && ctxt == 0 { a := NodSym(ODOT, var_, index.Sym)
a := NodSym(ODOT, var_, index.Sym) slicelit(ctxt, value, a, init)
slicelit(ctxt, value, a, init) } else if pass == 3 {
} else if pass == 3 { break
break
}
continue
} }
continue
case OARRAYLIT:
a := NodSym(ODOT, var_, index.Sym) a := NodSym(ODOT, var_, index.Sym)
arraylit(ctxt, pass, value, a, init) arraylit(ctxt, pass, value, a, init)
continue continue
...@@ -662,20 +649,19 @@ func arraylit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) { ...@@ -662,20 +649,19 @@ func arraylit(ctxt int, pass int, n *Node, var_ *Node, init *Nodes) {
value := r.Right value := r.Right
switch value.Op { switch value.Op {
case OARRAYLIT: case OSLICELIT:
if value.Type.IsSlice() { if pass == 1 && ctxt != 0 {
if pass == 1 && ctxt != 0 { a := Nod(OINDEX, var_, index)
a := Nod(OINDEX, var_, index) slicelit(ctxt, value, a, init)
slicelit(ctxt, value, a, init) } else if pass == 2 && ctxt == 0 {
} else if pass == 2 && ctxt == 0 { a := Nod(OINDEX, var_, index)
a := Nod(OINDEX, var_, index) slicelit(ctxt, value, a, init)
slicelit(ctxt, value, a, init) } else if pass == 3 {
} else if pass == 3 { break
break
}
continue
} }
continue
case OARRAYLIT:
a := Nod(OINDEX, var_, index) a := Nod(OINDEX, var_, index)
arraylit(ctxt, pass, value, a, init) arraylit(ctxt, pass, value, a, init)
continue continue
...@@ -825,10 +811,10 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) { ...@@ -825,10 +811,10 @@ func slicelit(ctxt int, n *Node, var_ *Node, init *Nodes) {
// TODO need to check bounds? // TODO need to check bounds?
switch value.Op { switch value.Op {
case OSLICELIT:
break
case OARRAYLIT: case OARRAYLIT:
if value.Type.IsSlice() {
break
}
arraylit(ctxt, 2, value, a, init) arraylit(ctxt, 2, value, a, init)
continue continue
...@@ -1079,15 +1065,10 @@ func anylit(ctxt int, n *Node, var_ *Node, init *Nodes) { ...@@ -1079,15 +1065,10 @@ func anylit(ctxt int, n *Node, var_ *Node, init *Nodes) {
structlit(ctxt, 3, n, var_, init) structlit(ctxt, 3, n, var_, init)
case OARRAYLIT: case OSLICELIT:
if t.IsSlice() { slicelit(ctxt, n, var_, init)
slicelit(ctxt, n, var_, init)
break
}
if !t.IsArray() {
Fatalf("anylit: not array")
}
case OARRAYLIT:
if var_.isSimpleName() && n.List.Len() > 4 { if var_.isSimpleName() && n.List.Len() > 4 {
if ctxt == 0 { if ctxt == 0 {
// lay out static data // lay out static data
...@@ -1162,7 +1143,7 @@ func oaslit(n *Node, init *Nodes) bool { ...@@ -1162,7 +1143,7 @@ func oaslit(n *Node, init *Nodes) bool {
// not a special composit literal assignment // not a special composit literal assignment
return false return false
case OSTRUCTLIT, OARRAYLIT, OMAPLIT: case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
if vmatch1(n.Left, n.Right) { if vmatch1(n.Left, n.Right) {
// not a special composit literal assignment // not a special composit literal assignment
return false return false
...@@ -1235,7 +1216,7 @@ func initplan(n *Node) { ...@@ -1235,7 +1216,7 @@ func initplan(n *Node) {
default: default:
Fatalf("initplan") Fatalf("initplan")
case OARRAYLIT: case OARRAYLIT, OSLICELIT:
for _, a := range n.List.Slice() { for _, a := range n.List.Slice() {
if a.Op != OKEY || !Smallintconst(a.Left) { if a.Op != OKEY || !Smallintconst(a.Left) {
Fatalf("initplan arraylit") Fatalf("initplan arraylit")
...@@ -1304,12 +1285,7 @@ func iszero(n *Node) bool { ...@@ -1304,12 +1285,7 @@ func iszero(n *Node) bool {
return u.Real.CmpFloat64(0) == 0 && u.Imag.CmpFloat64(0) == 0 return u.Real.CmpFloat64(0) == 0 && u.Imag.CmpFloat64(0) == 0
} }
case OARRAYLIT: case OARRAYLIT, OSTRUCTLIT:
if n.Type.IsSlice() {
break
}
fallthrough
case OSTRUCTLIT:
for _, n1 := range n.List.Slice() { for _, n1 := range n.List.Slice() {
if !iszero(n1.Right) { if !iszero(n1.Right) {
return false return false
...@@ -1322,7 +1298,7 @@ func iszero(n *Node) bool { ...@@ -1322,7 +1298,7 @@ func iszero(n *Node) bool {
} }
func isvaluelit(n *Node) bool { func isvaluelit(n *Node) bool {
return (n.Op == OARRAYLIT && n.Type.IsArray()) || n.Op == OSTRUCTLIT return n.Op == OARRAYLIT || n.Op == OSTRUCTLIT
} }
// gen_as_init attempts to emit static data for n and reports whether it succeeded. // gen_as_init attempts to emit static data for n and reports whether it succeeded.
......
...@@ -702,7 +702,7 @@ func (s *state) stmt(n *Node) { ...@@ -702,7 +702,7 @@ func (s *state) stmt(n *Node) {
rhs := n.Right rhs := n.Right
if rhs != nil { if rhs != nil {
switch rhs.Op { switch rhs.Op {
case OSTRUCTLIT, OARRAYLIT: case OSTRUCTLIT, OARRAYLIT, OSLICELIT:
// All literals with nonzero fields have already been // All literals with nonzero fields have already been
// rewritten during walk. Any that remain are just T{} // rewritten during walk. Any that remain are just T{}
// or equivalents. Use the zero value. // or equivalents. Use the zero value.
......
...@@ -1397,7 +1397,7 @@ func safeexpr(n *Node, init *Nodes) *Node { ...@@ -1397,7 +1397,7 @@ func safeexpr(n *Node, init *Nodes) *Node {
a = walkexpr(a, init) a = walkexpr(a, init)
return a return a
case OSTRUCTLIT, OARRAYLIT: case OSTRUCTLIT, OARRAYLIT, OSLICELIT:
if isStaticCompositeLiteral(n) { if isStaticCompositeLiteral(n) {
return n return n
} }
......
...@@ -362,7 +362,8 @@ const ( ...@@ -362,7 +362,8 @@ const (
OCOMPLIT // Right{List} (composite literal, not yet lowered to specific form) OCOMPLIT // Right{List} (composite literal, not yet lowered to specific form)
OMAPLIT // Type{List} (composite literal, Type is map) OMAPLIT // Type{List} (composite literal, Type is map)
OSTRUCTLIT // Type{List} (composite literal, Type is struct) OSTRUCTLIT // Type{List} (composite literal, Type is struct)
OARRAYLIT // Type{List} (composite literal, Type is array or slice) OARRAYLIT // Type{List} (composite literal, Type is array)
OSLICELIT // Type{List} (composite literal, Type is slice)
OPTRLIT // &Left (left is composite literal) OPTRLIT // &Left (left is composite literal)
OCONV // Type(Left) (type conversion) OCONV // Type(Left) (type conversion)
OCONVIFACE // Type(Left) (type conversion, to interface) OCONVIFACE // Type(Left) (type conversion, to interface)
......
...@@ -2941,8 +2941,10 @@ func typecheckcomplit(n *Node) *Node { ...@@ -2941,8 +2941,10 @@ func typecheckcomplit(n *Node) *Node {
} }
if t.IsSlice() { if t.IsSlice() {
n.Right = Nodintconst(length) n.Right = Nodintconst(length)
n.Op = OSLICELIT
} else {
n.Op = OARRAYLIT
} }
n.Op = OARRAYLIT
case TMAP: case TMAP:
hash := make(map[uint32][]*Node) hash := make(map[uint32][]*Node)
......
...@@ -1632,7 +1632,7 @@ opswitch: ...@@ -1632,7 +1632,7 @@ opswitch:
r.Type = n.Type r.Type = n.Type
n = r n = r
case OARRAYLIT, OMAPLIT, OSTRUCTLIT, OPTRLIT: case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT, OPTRLIT:
if isStaticCompositeLiteral(n) { if isStaticCompositeLiteral(n) {
// n can be directly represented in the read-only data section. // n can be directly represented in the read-only data section.
// Make direct reference to the static data. See issue 12841. // Make direct reference to the static data. See issue 12841.
...@@ -4051,6 +4051,7 @@ func candiscard(n *Node) bool { ...@@ -4051,6 +4051,7 @@ func candiscard(n *Node) bool {
OMAPLIT, OMAPLIT,
OSTRUCTLIT, OSTRUCTLIT,
OARRAYLIT, OARRAYLIT,
OSLICELIT,
OPTRLIT, OPTRLIT,
OCONV, OCONV,
OCONVIFACE, OCONVIFACE,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment