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

cmd/compile: add sliceBound

Add a constant for the magic -1 for slice bounds.
Use it.
Enforce more aggressively that bounds must be
slice, ddd, or non-negative.
Remove ad hoc check in plive.go.
Check bounds before constructing an array type
when typechecking.

All changes are manual.

Passes toolstash -cmp.

Change-Id: I9fd9cc789d7d4b4eea3b30b24037a254d3788add
Reviewed-on: https://go-review.googlesource.com/21348
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 4b95575b
...@@ -249,7 +249,7 @@ func dowidth(t *Type) { ...@@ -249,7 +249,7 @@ func dowidth(t *Type) {
w = t.Bound * t.Elem().Width w = t.Bound * t.Elem().Width
t.Align = t.Elem().Align t.Align = t.Elem().Align
} else if t.Bound == -1 { } else if t.IsSlice() {
w = int64(sizeof_Array) w = int64(sizeof_Array)
checkwidth(t.Elem()) checkwidth(t.Elem())
t.Align = uint8(Widthptr) t.Align = uint8(Widthptr)
......
...@@ -277,7 +277,7 @@ func (p *importer) typ() *Type { ...@@ -277,7 +277,7 @@ func (p *importer) typ() *Type {
case arrayTag, sliceTag: case arrayTag, sliceTag:
t = p.newtyp(TARRAY) t = p.newtyp(TARRAY)
t.Bound = -1 t.Bound = sliceBound
if i == arrayTag { if i == arrayTag {
t.Bound = p.int64() t.Bound = p.int64()
} }
...@@ -285,7 +285,7 @@ func (p *importer) typ() *Type { ...@@ -285,7 +285,7 @@ func (p *importer) typ() *Type {
case dddTag: case dddTag:
t = p.newtyp(TDDDFIELD) t = p.newtyp(TDDDFIELD)
t.Bound = -1 t.Bound = sliceBound
t.Type = p.typ() t.Type = p.typ()
case structTag: case structTag:
......
...@@ -918,11 +918,6 @@ func onebitwalktype1(t *Type, xoffset *int64, bv Bvec) { ...@@ -918,11 +918,6 @@ func onebitwalktype1(t *Type, xoffset *int64, bv Bvec) {
*xoffset += t.Width *xoffset += t.Width
case TARRAY: case TARRAY:
// The value of t.bound is -1 for slices types and >=0 for
// for fixed array types. All other values are invalid.
if t.Bound < -1 {
Fatalf("onebitwalktype1: invalid bound, %v", t)
}
if t.IsSlice() { if t.IsSlice() {
// struct { byte *array; uintgo len; uintgo cap; } // struct { byte *array; uintgo len; uintgo cap; }
if *xoffset&int64(Widthptr-1) != 0 { if *xoffset&int64(Widthptr-1) != 0 {
......
...@@ -70,7 +70,10 @@ const ( ...@@ -70,7 +70,10 @@ const (
NTYPE NTYPE
) )
const dddBound = -100 // arrays declared as [...]T start life with Bound=dddBound const (
sliceBound = -1 // slices have Bound=sliceBound
dddBound = -100 // arrays declared as [...]T start life with Bound=dddBound
)
// Types stores pointers to predeclared named types. // Types stores pointers to predeclared named types.
// //
...@@ -250,7 +253,7 @@ func typArray(elem *Type, bound int64) *Type { ...@@ -250,7 +253,7 @@ func typArray(elem *Type, bound int64) *Type {
func typSlice(elem *Type) *Type { func typSlice(elem *Type) *Type {
t := typ(TARRAY) t := typ(TARRAY)
t.Type = elem t.Type = elem
t.Bound = -1 t.Bound = sliceBound
return t return t
} }
...@@ -582,6 +585,7 @@ func (t *Type) isDDDArray() bool { ...@@ -582,6 +585,7 @@ func (t *Type) isDDDArray() bool {
if t.Etype != TARRAY { if t.Etype != TARRAY {
return false return false
} }
t.checkBound()
return t.Bound == dddBound return t.Bound == dddBound
} }
...@@ -878,12 +882,20 @@ func (t *Type) IsChan() bool { ...@@ -878,12 +882,20 @@ func (t *Type) IsChan() bool {
return t.Etype == TCHAN return t.Etype == TCHAN
} }
// checkBound enforces that Bound has an acceptable value.
func (t *Type) checkBound() {
if t.Bound != sliceBound && t.Bound < 0 && t.Bound != dddBound {
Fatalf("bad TARRAY bounds %d %s", t.Bound, t)
}
}
func (t *Type) IsSlice() bool { func (t *Type) IsSlice() bool {
// TODO(josharian): Change this to t.Bound == -1. t.checkBound()
return t.Etype == TARRAY && t.Bound < 0 return t.Etype == TARRAY && t.Bound == sliceBound
} }
func (t *Type) IsArray() bool { func (t *Type) IsArray() bool {
t.checkBound()
return t.Etype == TARRAY && t.Bound >= 0 return t.Etype == TARRAY && t.Bound >= 0
} }
...@@ -918,6 +930,7 @@ func (t *Type) NumElem() int64 { ...@@ -918,6 +930,7 @@ func (t *Type) NumElem() int64 {
if t.Etype != TARRAY { if t.Etype != TARRAY {
panic("NumElem on non-TARRAY") panic("NumElem on non-TARRAY")
} }
t.checkBound()
return t.Bound return t.Bound
} }
......
...@@ -369,17 +369,18 @@ OpSwitch: ...@@ -369,17 +369,18 @@ OpSwitch:
return n return n
} }
t = typArray(r.Type, v.U.(*Mpint).Int64())
if doesoverflow(v, Types[TINT]) { if doesoverflow(v, Types[TINT]) {
Yyerror("array bound is too large") Yyerror("array bound is too large")
n.Type = nil n.Type = nil
return n return n
} else if t.IsSlice() { }
bound := v.U.(*Mpint).Int64()
if bound < 0 {
Yyerror("array bound must be non-negative") Yyerror("array bound must be non-negative")
n.Type = nil n.Type = nil
return n return n
} }
t = typArray(r.Type, bound)
} }
n.Op = OTYPE n.Op = OTYPE
...@@ -2974,7 +2975,8 @@ func typecheckcomplit(n *Node) *Node { ...@@ -2974,7 +2975,8 @@ func typecheckcomplit(n *Node) *Node {
if t.IsArray() && length > t.Bound { if t.IsArray() && length > t.Bound {
setlineno(l) setlineno(l)
Yyerror("array index %d out of bounds [0:%d]", length-1, t.Bound) Yyerror("array index %d out of bounds [0:%d]", length-1, t.Bound)
t.Bound = -1 // no more errors // suppress any further errors out of bounds errors for the same type by pretending it is a slice
t.Bound = sliceBound
} }
} }
......
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