mirror of
https://github.com/golang/go
synced 2024-11-19 00:54:42 -07:00
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: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
4b95575bd4
commit
e775b8df7a
@ -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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
|
|
||||||
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) {
|
|||||||
*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 (
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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:
|
|||||||
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 {
|
|||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user