]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add sliceBound
authorJosh Bleecher Snyder <josharian@gmail.com>
Thu, 31 Mar 2016 16:29:39 +0000 (09:29 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 31 Mar 2016 18:41:30 +0000 (18:41 +0000)
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>
src/cmd/compile/internal/gc/align.go
src/cmd/compile/internal/gc/bimport.go
src/cmd/compile/internal/gc/plive.go
src/cmd/compile/internal/gc/type.go
src/cmd/compile/internal/gc/typecheck.go

index fd3fe0dce99324681b4ee694e526408e34bd28bf..85376c6b7e0caaeb6a3fc516e8dd6f0ed87b5033 100644 (file)
@@ -249,7 +249,7 @@ func dowidth(t *Type) {
 
                        w = t.Bound * t.Elem().Width
                        t.Align = t.Elem().Align
-               } else if t.Bound == -1 {
+               } else if t.IsSlice() {
                        w = int64(sizeof_Array)
                        checkwidth(t.Elem())
                        t.Align = uint8(Widthptr)
index 52b9b44a6954690d778ba76cc4ed4b04ed80b0de..082786acd933fa12aae3e01be43fc4973e79cc73 100644 (file)
@@ -277,7 +277,7 @@ func (p *importer) typ() *Type {
 
        case arrayTag, sliceTag:
                t = p.newtyp(TARRAY)
-               t.Bound = -1
+               t.Bound = sliceBound
                if i == arrayTag {
                        t.Bound = p.int64()
                }
@@ -285,7 +285,7 @@ func (p *importer) typ() *Type {
 
        case dddTag:
                t = p.newtyp(TDDDFIELD)
-               t.Bound = -1
+               t.Bound = sliceBound
                t.Type = p.typ()
 
        case structTag:
index 92200f3fc671966544f4ed6798f9fe8ed22a39b6..1e669201207ff20b6c132f7eea6e565760c01af2 100644 (file)
@@ -918,11 +918,6 @@ func onebitwalktype1(t *Type, xoffset *int64, bv Bvec) {
                *xoffset += t.Width
 
        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() {
                        // struct { byte *array; uintgo len; uintgo cap; }
                        if *xoffset&int64(Widthptr-1) != 0 {
index 765b2059a3c58ec4fb14641048999f706802f903..e94ec85e604508e4ef76b0199fddc081e06f3929 100644 (file)
@@ -70,7 +70,10 @@ const (
        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.
 //
@@ -250,7 +253,7 @@ func typArray(elem *Type, bound int64) *Type {
 func typSlice(elem *Type) *Type {
        t := typ(TARRAY)
        t.Type = elem
-       t.Bound = -1
+       t.Bound = sliceBound
        return t
 }
 
@@ -582,6 +585,7 @@ func (t *Type) isDDDArray() bool {
        if t.Etype != TARRAY {
                return false
        }
+       t.checkBound()
        return t.Bound == dddBound
 }
 
@@ -878,12 +882,20 @@ func (t *Type) IsChan() bool {
        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 {
-       // TODO(josharian): Change this to t.Bound == -1.
-       return t.Etype == TARRAY && t.Bound < 0
+       t.checkBound()
+       return t.Etype == TARRAY && t.Bound == sliceBound
 }
 
 func (t *Type) IsArray() bool {
+       t.checkBound()
        return t.Etype == TARRAY && t.Bound >= 0
 }
 
@@ -918,6 +930,7 @@ func (t *Type) NumElem() int64 {
        if t.Etype != TARRAY {
                panic("NumElem on non-TARRAY")
        }
+       t.checkBound()
        return t.Bound
 }
 
index 260f410275eda0069ea057f21390c95c32a28d49..5bcc8c96160d7774c8acb7aff9eaf83b0285f4ae 100644 (file)
@@ -369,17 +369,18 @@ OpSwitch:
                                return n
                        }
 
-                       t = typArray(r.Type, v.U.(*Mpint).Int64())
-
                        if doesoverflow(v, Types[TINT]) {
                                Yyerror("array bound is too large")
                                n.Type = nil
                                return n
-                       } else if t.IsSlice() {
+                       }
+                       bound := v.U.(*Mpint).Int64()
+                       if bound < 0 {
                                Yyerror("array bound must be non-negative")
                                n.Type = nil
                                return n
                        }
+                       t = typArray(r.Type, bound)
                }
 
                n.Op = OTYPE
@@ -2974,7 +2975,8 @@ func typecheckcomplit(n *Node) *Node {
                                if t.IsArray() && length > t.Bound {
                                        setlineno(l)
                                        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
                                }
                        }