diff options
author | Russ Cox <rsc@golang.org> | 2010-02-01 23:05:15 -0800 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2010-02-01 23:05:15 -0800 |
commit | 6546057f38c6c3c395a516df36669b86add35c83 (patch) | |
tree | 2f53c14e0b635beace769b5df1ad38cfed9aaae5 /src | |
parent | a0737a07c2e95132c32f0ac6f32bb811bd23c537 (diff) | |
download | golang-6546057f38c6c3c395a516df36669b86add35c83.tar.gz |
gc: bug246
R=ken2
CC=golang-dev
http://codereview.appspot.com/198057
Diffstat (limited to 'src')
-rw-r--r-- | src/cmd/gc/align.c | 5 | ||||
-rw-r--r-- | src/cmd/gc/const.c | 11 | ||||
-rw-r--r-- | src/cmd/gc/go.h | 1 | ||||
-rw-r--r-- | src/cmd/gc/walk.c | 2 |
4 files changed, 17 insertions, 2 deletions
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c index 7a27a040c..dfb9f9e89 100644 --- a/src/cmd/gc/align.c +++ b/src/cmd/gc/align.c @@ -410,6 +410,7 @@ typeinit(void) okforarith[i] = 1; okforadd[i] = 1; okforand[i] = 1; + okforconst[i] = 1; issimple[i] = 1; minintval[i] = mal(sizeof(*minintval[i])); maxintval[i] = mal(sizeof(*maxintval[i])); @@ -419,6 +420,7 @@ typeinit(void) okforcmp[i] = 1; okforadd[i] = 1; okforarith[i] = 1; + okforconst[i] = 1; issimple[i] = 1; minfltval[i] = mal(sizeof(*minfltval[i])); maxfltval[i] = mal(sizeof(*maxfltval[i])); @@ -434,6 +436,9 @@ typeinit(void) okforcap[TARRAY] = 1; okforcap[TCHAN] = 1; + okforconst[TBOOL] = 1; + okforconst[TSTRING] = 1; + okforlen[TARRAY] = 1; okforlen[TCHAN] = 1; okforlen[TMAP] = 1; diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c index d7d6e3503..a78c122fe 100644 --- a/src/cmd/gc/const.c +++ b/src/cmd/gc/const.c @@ -93,6 +93,9 @@ convlit1(Node **np, Type *t, int explicit) } return; case OLITERAL: + // target is invalid type for a constant? leave alone. + if(!okforconst[t->etype] && n->type->etype != TNIL) + return; break; case OLSH: case ORSH: @@ -105,6 +108,7 @@ convlit1(Node **np, Type *t, int explicit) n->type = t; return; } + // avoided repeated calculations, errors if(cvttype(n->type, t) == 1) { n->type = t; @@ -345,7 +349,6 @@ evconst(Node *n) case OANDNOT: case OARRAYBYTESTR: case OCOM: - case OCONV: case ODIV: case OEQ: case OGE: @@ -365,6 +368,12 @@ evconst(Node *n) case OSUB: case OXOR: break; + case OCONV: + if(n->type == T) + return; + if(!okforconst[n->type->etype] && n->type->etype != TNIL) + return; + break; } nl = n->left; diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 16cf87f0c..98a159701 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -680,6 +680,7 @@ EXTERN uchar okforbool[NTYPE]; EXTERN uchar okforcap[NTYPE]; EXTERN uchar okforlen[NTYPE]; EXTERN uchar okforarith[NTYPE]; +EXTERN uchar okforconst[NTYPE]; EXTERN uchar* okfor[OEND]; EXTERN uchar iscmp[OEND]; diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index f560d5be2..ffdd17a95 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -182,7 +182,7 @@ walkdef(Node *n) t = n->type; if(t != T) { convlit(&e, t); - if(!isint[t->etype] && !isfloat[t->etype] && t->etype != TSTRING && t->etype != TBOOL) + if(!okforconst[t->etype]) yyerror("invalid constant type %T", t); } n->val = e->val; |