Commit 5ab8f00b authored by Russ Cox's avatar Russ Cox

gc: diagnose invalid array bounds

Fixes #587.

R=ken2
CC=golang-dev
https://golang.org/cl/207085
parent 9f77e7ea
...@@ -6,9 +6,7 @@ ...@@ -6,9 +6,7 @@
#define TUP(x,y) (((x)<<16)|(y)) #define TUP(x,y) (((x)<<16)|(y))
static Val toflt(Val); static Val toflt(Val);
static Val toint(Val);
static Val tostr(Val); static Val tostr(Val);
static void overflow(Val, Type*);
static Val copyval(Val); static Val copyval(Val);
/* /*
...@@ -236,7 +234,7 @@ toflt(Val v) ...@@ -236,7 +234,7 @@ toflt(Val v)
return v; return v;
} }
static Val Val
toint(Val v) toint(Val v)
{ {
Mpint *i; Mpint *i;
...@@ -251,7 +249,7 @@ toint(Val v) ...@@ -251,7 +249,7 @@ toint(Val v)
return v; return v;
} }
static void void
overflow(Val v, Type *t) overflow(Val v, Type *t)
{ {
// v has already been converted // v has already been converted
......
...@@ -1088,6 +1088,8 @@ int consttype(Node*); ...@@ -1088,6 +1088,8 @@ int consttype(Node*);
int isconst(Node*, int); int isconst(Node*, int);
Mpflt* truncfltlit(Mpflt*, Type*); Mpflt* truncfltlit(Mpflt*, Type*);
void convconst(Node*, Type*, Val*); void convconst(Node*, Type*, Val*);
Val toint(Val);
void overflow(Val, Type*);
/* /*
* align.c * align.c
......
...@@ -51,9 +51,10 @@ typecheck(Node **np, int top) ...@@ -51,9 +51,10 @@ typecheck(Node **np, int top)
int et, op; int et, op;
Node *n, *l, *r; Node *n, *l, *r;
NodeList *args; NodeList *args;
int lno, ok, ntop; int lno, ok, ntop, ct;
Type *t; Type *t;
Sym *sym; Sym *sym;
Val v;
// cannot type check until all the source has been parsed // cannot type check until all the source has been parsed
if(!typecheckok) if(!typecheckok)
...@@ -157,29 +158,28 @@ reswitch: ...@@ -157,29 +158,28 @@ reswitch:
l = n->left; l = n->left;
r = n->right; r = n->right;
if(l == nil) { if(l == nil) {
t->bound = -1; t->bound = -1; // slice
} else if(l->op == ODDD) {
t->bound = -100; // to be filled in
} else { } else {
if(l->op != ODDD) l = typecheck(&n->left, Erv);
typecheck(&l, Erv | Etype); switch(consttype(l)) {
switch(l->op) { case CTINT:
v = l->val;
break;
case CTFLT:
v = toint(l->val);
break;
default: default:
yyerror("invalid array bound %#N", l); yyerror("invalid array bound %#N", l);
goto error; 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); typecheck(&r, Etype);
if(r->type == T) if(r->type == T)
......
// $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))
}
}
// 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"
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