]> Cypherpunks repositories - gostls13.git/commitdiff
gc: diagnose invalid array bounds
authorRuss Cox <rsc@golang.org>
Fri, 12 Feb 2010 21:59:02 +0000 (13:59 -0800)
committerRuss Cox <rsc@golang.org>
Fri, 12 Feb 2010 21:59:02 +0000 (13:59 -0800)
Fixes #587.

R=ken2
CC=golang-dev
https://golang.org/cl/207085

src/cmd/gc/const.c
src/cmd/gc/go.h
src/cmd/gc/typecheck.c
test/fixedbugs/bug254.go [new file with mode: 0644]
test/fixedbugs/bug255.go [new file with mode: 0644]

index a78c122fecb48c716947548005c2fc7ec90595c5..d541c60c542fb2c42e7058c28b8b4443a39f8bf9 100644 (file)
@@ -6,9 +6,7 @@
 #define        TUP(x,y)        (((x)<<16)|(y))
 
 static Val toflt(Val);
-static Val toint(Val);
 static Val tostr(Val);
-static void overflow(Val, Type*);
 static Val copyval(Val);
 
 /*
@@ -236,7 +234,7 @@ toflt(Val v)
        return v;
 }
 
-static Val
+Val
 toint(Val v)
 {
        Mpint *i;
@@ -251,7 +249,7 @@ toint(Val v)
        return v;
 }
 
-static void
+void
 overflow(Val v, Type *t)
 {
        // v has already been converted
index 98a15970118ce1f697fc4e0047635c65a31d6ff1..f3bab1355dc2706b27a8ea460853976479e49147 100644 (file)
@@ -1088,6 +1088,8 @@ int       consttype(Node*);
 int    isconst(Node*, int);
 Mpflt* truncfltlit(Mpflt*, Type*);
 void   convconst(Node*, Type*, Val*);
+Val    toint(Val);
+void   overflow(Val, Type*);
 
 /*
  *     align.c
index 11d142eebb5fae18ccd7d6b3fe2416acc6830943..a7d95a9cd5a801d0fb3fa4025182c4fe295e3f37 100644 (file)
@@ -51,9 +51,10 @@ typecheck(Node **np, int top)
        int et, op;
        Node *n, *l, *r;
        NodeList *args;
-       int lno, ok, ntop;
+       int lno, ok, ntop, ct;
        Type *t;
        Sym *sym;
+       Val v;
 
        // cannot type check until all the source has been parsed
        if(!typecheckok)
@@ -157,29 +158,28 @@ reswitch:
                l = n->left;
                r = n->right;
                if(l == nil) {
-                       t->bound = -1;
+                       t->bound = -1;  // slice
+               } else if(l->op == ODDD) {
+                       t->bound = -100;        // to be filled in
                } else {
-                       if(l->op != ODDD)
-                               typecheck(&l, Erv | Etype);
-                       switch(l->op) {
+                       l = typecheck(&n->left, Erv);
+                       switch(consttype(l)) {
+                       case CTINT:
+                               v = l->val;
+                               break;
+                       case CTFLT:
+                               v = toint(l->val);
+                               break;
                        default:
                                yyerror("invalid array bound %#N", l);
                                goto error;
-
-                       case OLITERAL:
-                               if(consttype(l) == CTINT) {
-                                       t->bound = mpgetfix(l->val.u.xval);
-                                       if(t->bound < 0) {
-                                               yyerror("array bound must be non-negative");
-                                               goto error;
-                                       }
-                               }
-                               break;
-
-                       case ODDD:
-                               t->bound = -100;
-                               break;
                        }
+                       t->bound = mpgetfix(v.u.xval);
+                       if(t->bound < 0) {
+                               yyerror("array bound must be non-negative");
+                               goto error;
+                       } else
+                               overflow(v, types[TINT]);
                }
                typecheck(&r, Etype);
                if(r->type == T)
diff --git a/test/fixedbugs/bug254.go b/test/fixedbugs/bug254.go
new file mode 100644 (file)
index 0000000..f351eb8
--- /dev/null
@@ -0,0 +1,16 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug254
+
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var a [10]int
+var b [1e1]int
+
+func main() {
+       if len(a) != 10 || len(b) != 10 {
+               panicln("len", len(a), len(b))
+       }
+}
diff --git a/test/fixedbugs/bug255.go b/test/fixedbugs/bug255.go
new file mode 100644 (file)
index 0000000..4003a78
--- /dev/null
@@ -0,0 +1,15 @@
+// errchk $G -e $D/$F.go
+
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var a [10]int  // ok
+var b [1e1]int // ok
+var c [1.5]int // ERROR "truncated"
+var d ["abc"]int       // ERROR "invalid array bound"
+var e [nil]int // ERROR "invalid array bound"
+var f [e]int   // ERROR "invalid array bound"
+var g [1<<65]int       // ERROR "overflows"