summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2008-10-16 15:59:31 -0700
committerRuss Cox <rsc@golang.org>2008-10-16 15:59:31 -0700
commit9f032217e78085cabbc4d065f3ab2a8a8c74cee7 (patch)
treee0a34202934220fbb1b8af43881269f95e53121e /src
parent6c66c1d30ab1acccbf37ab7ece81b9949950c2e2 (diff)
downloadgolang-9f032217e78085cabbc4d065f3ab2a8a8c74cee7.tar.gz
diagnose various conversion problems
R=ken OCL=17320 CL=17320
Diffstat (limited to 'src')
-rw-r--r--src/cmd/gc/const.c28
-rw-r--r--src/cmd/gc/dcl.c7
-rw-r--r--src/cmd/gc/go.h2
-rw-r--r--src/cmd/gc/go.y4
-rw-r--r--src/cmd/gc/lex.c1
-rw-r--r--src/cmd/gc/subr.c46
-rw-r--r--src/cmd/gc/walk.c7
7 files changed, 78 insertions, 17 deletions
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index b624e2aba..9ee33ad11 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -8,7 +8,7 @@
void
convlit(Node *n, Type *t)
{
- int et;
+ int et, wt;
if(n == N || t == T)
return;
@@ -25,18 +25,10 @@ convlit(Node *n, Type *t)
}
et = t->etype;
- switch(et) {
- case TARRAY:
- case TFUNC:
- case TCHAN:
- case TMAP:
- case TSTRUCT:
-// case TPTR32:
-// case TPTR64:
- return;
- }
- switch(whatis(n)) {
+ wt = whatis(n);
+
+ switch(wt) {
default:
goto bad1;
@@ -125,6 +117,8 @@ convlit(Node *n, Type *t)
goto bad2;
if(mpcmpfltfix(fv, maxintval[et]) > 0)
goto bad2;
+ if(floor(mpgetflt(fv)) != mpgetflt(fv))
+ goto bad3;
n->val.u.xval = mal(sizeof(*n->val.u.xval));
mpmovefltfix(n->val.u.xval, fv);
n->val.ctype = CTINT;
@@ -144,12 +138,16 @@ convlit(Node *n, Type *t)
return;
bad1:
- yyerror("illegal conversion of constant to %T", t);
+ yyerror("illegal conversion of %W to %T", wt, t);
return;
bad2:
yyerror("overflow converting constant to %T", t);
return;
+
+bad3:
+ yyerror("cannot convert non-integer constant to %T", t);
+ return;
}
void
@@ -212,7 +210,7 @@ evconst(Node *n)
nl->val.ctype = CTFLT;
wl = whatis(nl);
} else {
- yyerror("illegal combination of literals %E %E", nl->etype, nr->etype);
+ yyerror("illegal combination of literals %O %E, %E", n->op, wl, wr);
return;
}
}
@@ -230,7 +228,7 @@ evconst(Node *n)
switch(TUP(n->op, wl)) {
default:
- yyerror("illegal combination of literals %O %E", n->op, nl->etype);
+ yyerror("illegal literal %O %E", n->op, wl);
return;
case TUP(OADD, Wlitint):
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index 725bfd2ae..6368fa4bd 100644
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -27,6 +27,13 @@ dodclvar(Node *n, Type *t)
dodclvar(n->left, t);
dowidth(t);
+
+ // in case of type checking error,
+ // use "undefined" type for variable type,
+ // to avoid fatal in addvar.
+ if(t == T)
+ t = typ(TFORW);
+
addvar(n, t, dclcontext);
if(exportadj)
exportsym(n->sym);
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 92dc1260c..42b068c8d 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -598,6 +598,7 @@ Node* syslook(char*, int);
Node* treecopy(Node*);
int isselect(Node*);
void tempname(Node*, Type*);
+int iscomposite(Type*);
Type** getthis(Type*);
Type** getoutarg(Type*);
@@ -621,6 +622,7 @@ int Oconv(Fmt*);
int Sconv(Fmt*);
int Tconv(Fmt*);
int Nconv(Fmt*);
+int Wconv(Fmt*);
int Zconv(Fmt*);
/*
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 3e69c305e..4afc1c6e8 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -872,6 +872,8 @@ pexpr:
{
$$ = nod(OCONV, $3, N);
$$->type = oldtype($1);
+ if(iscomposite($$->type))
+ yyerror("illegal conversion type %T", $$->type);
}
| convtype '{' braced_keyexpr_list '}'
{
@@ -879,6 +881,8 @@ pexpr:
$$ = rev($3);
if($$ == N)
$$ = nod(OEMPTY, N, N);
+ if(!iscomposite($1))
+ yyerror("illegal composite literal type %T", $1);
$$ = nod(OCONV, $$, N);
$$->type = $1;
}
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 41bc1c74b..d0bff2741 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -53,6 +53,7 @@ mainlex(int argc, char *argv[])
fmtinstall('Z', Zconv); // escaped string
fmtinstall('L', Lconv); // line number
fmtinstall('B', Bconv); // big numbers
+ fmtinstall('W', Wconv); // whatis numbers (Wlitint)
lexinit();
lineno = 1;
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 76c585d67..c086aeb85 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -822,6 +822,8 @@ etnames[] =
[TSTRING] = "STRING",
[TCHAN] = "CHAN",
[TANY] = "ANY",
+ [TFORWINTER] = "FORWINTER",
+ [TFORWSTRUCT] = "FORWSTRUCT",
};
int
@@ -1327,6 +1329,36 @@ out:
return fmtstrcpy(fp, buf);
}
+
+static char*
+wnames[] =
+{
+ [Wnil] = "Wnil",
+ [Wtnil] = "Wtnil",
+
+ [Wtfloat] = "Wtfloat",
+ [Wtint] = "Wtint",
+ [Wtbool] = "Wtbool",
+ [Wtstr] = "Wtstr",
+
+ [Wlitfloat] = "float constant",
+ [Wlitint] = "int constant",
+ [Wlitbool] = "bool",
+ [Wlitstr] = "string",
+ [Wlitnil] = "nil",
+};
+
+int
+Wconv(Fmt *fp)
+{
+ char buf[500];
+ int w;
+
+ w = va_arg(fp->args, int);
+ if(w < 0 || w >= nelem(wnames) || wnames[w] == nil)
+ return fmtprint(fp, "W-%d", w);
+ return fmtstrcpy(fp, wnames[w]);
+}
int
isnil(Node *n)
{
@@ -1466,6 +1498,20 @@ out:
return t;
}
+int
+iscomposite(Type *t)
+{
+ if(t == T)
+ return 0;
+ switch(t->etype) {
+ case TMAP:
+ case TARRAY:
+ case TSTRUCT:
+ return 1;
+ }
+ return 0;
+}
+
Sym*
globalsig(Type *t)
{
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 761a723dc..610051a50 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -521,13 +521,15 @@ loop:
l = n->left;
if(l == N)
goto ret;
+
walktype(l, Erv);
t = n->type;
if(t == T)
goto ret;
- convlit(l, t);
+ if(!iscomposite(t))
+ convlit(l, t);
// nil conversion
if(eqtype(t, l->type, 0)) {
@@ -589,7 +591,8 @@ loop:
goto ret;
}
- badtype(n->op, l->type, t);
+ if(l->type != T)
+ yyerror("cannot convert %T to %T", l->type, t);
goto ret;
case ORETURN: