summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-02-01 23:05:15 -0800
committerRuss Cox <rsc@golang.org>2010-02-01 23:05:15 -0800
commit6546057f38c6c3c395a516df36669b86add35c83 (patch)
tree2f53c14e0b635beace769b5df1ad38cfed9aaae5 /src
parenta0737a07c2e95132c32f0ac6f32bb811bd23c537 (diff)
downloadgolang-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.c5
-rw-r--r--src/cmd/gc/const.c11
-rw-r--r--src/cmd/gc/go.h1
-rw-r--r--src/cmd/gc/walk.c2
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;