Commit 8f194bf5 authored by Russ Cox's avatar Russ Cox

make 6g constants behave as ken proposes. (i hope.)

various bug fixes and tests involving constants.

test/const1.go is the major new test case.

R=ken
OCL=26216
CL=26224
parent 9b5d8232
......@@ -146,11 +146,11 @@ cgen(Node *n, Node *res)
case ONOT:
p1 = gbranch(AJMP, T);
p2 = pc;
gmove(booltrue, res);
gmove(nodbool(1), res);
p3 = gbranch(AJMP, T);
patch(p1, pc);
bgen(n, 1, p2);
gmove(boolfalse, res);
gmove(nodbool(0), res);
patch(p3, pc);
goto ret;
......@@ -408,7 +408,7 @@ agen(Node *n, Node *res)
if(nr->addable)
goto irad;
if(nl->addable) {
if(whatis(nr) != Wlitint) {
if(!isconst(nr, CTINT)) {
regalloc(&n1, nr->type, N);
cgen(nr, &n1);
}
......@@ -423,7 +423,7 @@ agen(Node *n, Node *res)
irad:
regalloc(&n3, types[tptr], res);
agen(nl, &n3);
if(whatis(nr) != Wlitint) {
if(!isconst(nr, CTINT)) {
regalloc(&n1, nr->type, N);
cgen(nr, &n1);
}
......@@ -438,7 +438,7 @@ agen(Node *n, Node *res)
fatal("index is zero width");
// constant index
if(whatis(nr) == Wlitint) {
if(isconst(nr, CTINT)) {
v = mpgetfix(nr->val.u.xval);
if(isslice(nl->type)) {
......@@ -618,7 +618,7 @@ bgen(Node *n, int true, Prog *to)
}
if(n == N)
n = booltrue;
n = nodbool(1);
nl = n->left;
nr = n->right;
......
......@@ -345,15 +345,6 @@ nodconst(Node *n, Type *t, vlong v)
case TFLOAT64:
case TFLOAT80:
fatal("nodconst: bad type %T", t);
case TPTR32:
case TPTR64:
case TUINT8:
case TUINT16:
case TUINT32:
case TUINT64:
n->val.ctype = CTUINT;
break;
}
}
......@@ -1102,8 +1093,6 @@ naddr(Node *n, Addr *a)
a->dval = mpgetflt(n->val.u.fval);
break;
case CTINT:
case CTSINT:
case CTUINT:
a->sym = S;
a->type = D_CONST;
a->offset = mpgetfix(n->val.u.xval);
......@@ -2057,7 +2046,7 @@ oindex:
}
w = n->type->width;
if(whatis(r) == Wlitint)
if(isconst(r, CTINT))
goto oindex_const;
switch(w) {
......
This diff is collapsed.
......@@ -23,6 +23,8 @@ dodclvar(Node *n, Type *t)
if(n == N)
return;
if(t != T && (t->etype == TIDEAL || t->etype == TNIL))
fatal("dodclvar %T", t);
for(; n->op == OLIST; n = n->right)
dodclvar(n->left, t);
......@@ -1284,7 +1286,7 @@ fninit(Node *n)
r = list(r, a);
// (4)
a = nod(OAS, done, booltrue);
a = nod(OAS, done, nodbool(1));
r = list(r, a);
// (5)
......@@ -1460,7 +1462,7 @@ loop:
a = nod(OAS, v, N);
if(t == T) {
gettype(e, a);
defaultlit(e);
defaultlit(e, T);
dodclvar(v, e->type);
} else
dodclvar(v, t);
......@@ -1475,7 +1477,7 @@ loop:
/*
* declare constants from grammar
* new_name_list [type] [= expr_list]
* new_name_list [[type] = expr_list]
*/
void
constiter(Node *vv, Type *t, Node *cc)
......@@ -1483,9 +1485,14 @@ constiter(Node *vv, Type *t, Node *cc)
Iter viter, citer;
Node *v, *c;
if(cc == N)
if(cc == N) {
if(t != T)
yyerror("constdcl cannot have type without expr");
cc = lastconst;
t = lasttype;
}
lastconst = cc;
lasttype = t;
vv = rev(vv);
cc = rev(treecopy(cc));
......@@ -1499,7 +1506,7 @@ loop:
}
if(v == N || c == N) {
yyerror("shape error in var dcl");
yyerror("shape error in const dcl");
iota += 1;
return;
}
......@@ -1507,6 +1514,8 @@ loop:
gettype(c, N);
if(t != T)
convlit(c, t);
if(t == T)
lasttype = c->type;
dodclconst(v, c);
v = listnext(&viter);
......@@ -1587,5 +1596,6 @@ yes:
mpmovecfix(val.u.xval, v);
n = nod(OLITERAL, N, N);
n->val = val;
n->type = types[TINT];
return n;
}
......@@ -110,7 +110,7 @@ dumpexportconst(Sym *s)
Bprint(bout, "\t");
Bprint(bout, "const %lS", s);
if(t != T)
if(t != T && t->etype != TIDEAL)
Bprint(bout, " %#T", t);
Bprint(bout, " = ");
......@@ -118,8 +118,6 @@ dumpexportconst(Sym *s)
default:
fatal("dumpexportconst: unknown ctype: %S", s);
case CTINT:
case CTSINT:
case CTUINT:
Bprint(bout, "%B\n", n->val.u.xval);
break;
case CTBOOL:
......@@ -343,18 +341,14 @@ mypackage(Node *ss)
}
void
importconst(Node *ss, Type *t, Val *v)
importconst(Node *ss, Type *t, Node *n)
{
Node *n;
Sym *s;
if(!exportname(ss->sym->name) && !mypackage(ss))
return;
n = nod(OLITERAL, N, N);
n->val = *v;
n->type = t;
convlit(n, t);
s = importsym(ss, LACONST);
if(s->oconst != N) {
// TODO: check if already the same.
......@@ -363,7 +357,7 @@ importconst(Node *ss, Type *t, Val *v)
dodclconst(newname(s), n);
if(debug['e'])
if(debug['E'])
print("import const %S\n", s);
}
......@@ -385,7 +379,7 @@ importvar(Node *ss, Type *t, int ctxt)
checkwidth(t);
addvar(newname(s), t, ctxt);
if(debug['e'])
if(debug['E'])
print("import var %S %lT\n", s, t);
}
......@@ -410,7 +404,7 @@ importtype(Node *ss, Type *t)
s->otype->sym = s;
checkwidth(s->otype);
if(debug['e'])
if(debug['E'])
print("import type %S %lT\n", s, t);
}
......
......@@ -371,6 +371,10 @@ enum
TFORWSTRUCT,
TFORWINTER,
// pseudo-types for literals
TIDEAL,
TNIL,
NTYPE,
};
enum
......@@ -378,35 +382,12 @@ enum
CTxxx,
CTINT,
CTSINT,
CTUINT,
CTFLT,
CTSTR,
CTBOOL,
CTNIL,
};
enum
{
/* indications for whatis() */
Wnil = 0,
Wtnil,
Wtfloat,
Wtint,
Wtbool,
Wtstr,
Wlitfloat,
Wlitint,
Wlitbool,
Wlitstr,
Wlitnil,
Wtunkn,
};
enum
{
/* types of channel */
......@@ -518,10 +499,9 @@ EXTERN int dclcontext; // PEXTERN/PAUTO
EXTERN int importflag;
EXTERN int inimportsys;
EXTERN Node* booltrue;
EXTERN Node* boolfalse;
EXTERN uint32 iota;
EXTERN Node* lastconst;
EXTERN Type* lasttype;
EXTERN int32 vargen;
EXTERN int32 exportgen;
EXTERN int32 maxarg;
......@@ -594,7 +574,7 @@ void mpdivfixfix(Mpint *a, Mpint *b);
void mpmodfixfix(Mpint *a, Mpint *b);
void mpatofix(Mpint *a, char *s);
void mpatoflt(Mpflt *a, char *s);
void mpmovefltfix(Mpint *a, Mpflt *b);
int mpmovefltfix(Mpint *a, Mpflt *b);
void mpmovefixflt(Mpflt *a, Mpint *b);
int Bconv(Fmt*);
......@@ -611,7 +591,7 @@ void mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d);
void mpdivfract(Mpint *a, Mpint *b);
void mpnegfix(Mpint *a);
void mpandfixfix(Mpint *a, Mpint *b);
void mpnotandfixfix(Mpint *a, Mpint *b);
void mpandnotfixfix(Mpint *a, Mpint *b);
void mplshfixfix(Mpint *a, Mpint *b);
void mporfixfix(Mpint *a, Mpint *b);
void mprshfixfix(Mpint *a, Mpint *b);
......@@ -651,6 +631,7 @@ void fatal(char*, ...);
void linehist(char*, int32);
int32 setlineno(Node*);
Node* nod(int, Node*, Node*);
Node* nodlit(Val);
Node* list(Node*, Node*);
Type* typ(int);
Dcl* dcl(void);
......@@ -680,9 +661,10 @@ void argtype(Node*, Type*);
int eqargs(Type*, Type*);
uint32 typehash(Type*, int);
void frame(int);
Node* literal(int32);
Node* dobad(void);
Node* nodintconst(int32);
Node* nodintconst(int64);
Node* nodnil(void);
Node* nodbool(int);
void ullmancalc(Node*);
void badtype(int, Type*, Type*);
Type* ptrto(Type*);
......@@ -735,7 +717,8 @@ void dodclvar(Node*, Type*);
Type* dodcltype(Type*);
void updatetype(Type*, Type*);
void dodclconst(Node*, Node*);
void defaultlit(Node*);
void defaultlit(Node*, Type*);
void defaultlit2(Node*, Node*);
int listcount(Node*);
void addmethod(Node*, Type*, int);
Node* methodname(Node*, Type*);
......@@ -806,7 +789,7 @@ void doimport6(Node*, Node*);
void doimport7(Node*, Node*);
void doimport8(Node*, Val*, Node*);
void doimport9(Sym*, Node*);
void importconst(Node *ss, Type *t, Val *v);
void importconst(Node *ss, Type *t, Node *v);
void importmethod(Sym *s, Type *t);
void importtype(Node *ss, Type *t);
void importvar(Node *ss, Type *t, int ctxt);
......@@ -826,7 +809,6 @@ void walkas(Node*);
void walkbool(Node*);
void walkswitch(Node*);
void walkselect(Node*);
int whatis(Node*);
void walkdot(Node*);
Node* ascompatee(int, Node**, Node**);
Node* ascompatet(int, Node**, Type**, int);
......@@ -871,6 +853,8 @@ void convlit(Node*, Type*);
void evconst(Node*);
int cmpslit(Node *l, Node *r);
int smallintconst(Node*);
int consttype(Node*);
int isconst(Node*, int);
/*
* gen.c/gsubr.c/obj.c
......
......@@ -73,7 +73,7 @@
%type <type> indcl fnlitdcl dotdotdot
%type <val> oliteral
%type <val> hidden_constant
%type <node> hidden_constant
%type <node> hidden_dcl hidden_structdcl
%type <type> hidden_type hidden_type1 hidden_type2
%type <node> hidden_structdcl_list ohidden_structdcl_list hidden_structdcl_list_r
......@@ -447,12 +447,12 @@ simple_stmt:
}
| expr LINC
{
$$ = nod(OASOP, $1, literal(1));
$$ = nod(OASOP, $1, nodintconst(1));
$$->etype = OADD;
}
| expr LDEC
{
$$ = nod(OASOP, $1, literal(1));
$$ = nod(OASOP, $1, nodintconst(1));
$$->etype = OSUB;
}
......@@ -822,33 +822,32 @@ uexpr:
pexpr:
LLITERAL
{
$$ = nod(OLITERAL, N, N);
$$->val = $1;
if($1.ctype == CTSTR)
$$->type = types[TSTRING];
}
| laconst
{
$$ = nod(OLITERAL, N, N);
$$->val = $1->oconst->val;
$$->type = $1->oconst->type;
$$ = nodlit($1);
}
| LNIL
{
$$ = nod(OLITERAL, N, N);
$$->val.ctype = CTNIL;
Val v;
v.ctype = CTNIL;
$$ = nodlit(v);
}
| LTRUE
{
$$ = booltrue;
$$ = nodbool(1);
}
| LFALSE
{
$$ = boolfalse;
$$ = nodbool(0);
}
| laconst
{
$$ = nod(OLITERAL, N, N);
$$->val = $1->oconst->val;
$$->type = $1->oconst->type;
}
| LIOTA
{
$$ = literal(iota);
$$ = nodintconst(iota);
$$->iota = 1; // flag to reevaluate on copy
}
| name
......@@ -1828,11 +1827,11 @@ hidden_import:
}
| LCONST hidden_pkg_importsym '=' hidden_constant
{
importconst($2, T, &$4);
importconst($2, types[TIDEAL], $4);
}
| LCONST hidden_pkg_importsym hidden_type '=' hidden_constant
{
importconst($2, $3, &$5);
importconst($2, $3, $5);
}
| LTYPE hidden_pkg_importsym hidden_type
{
......@@ -1870,11 +1869,7 @@ hidden_type1:
}
| '[' LLITERAL ']' hidden_type
{
Node *n;
n = nod(OLITERAL, N, N);
n->val = $2;
$$ = aindex(n, $4);
$$ = aindex(nodlit($2), $4);
}
| LMAP '[' hidden_type ']' hidden_type
{
......@@ -1978,15 +1973,18 @@ hidden_funres:
hidden_constant:
LLITERAL
{
$$ = nodlit($1);
}
| '-' LLITERAL
{
$$ = $2;
switch($$.ctype){
$$ = nodlit($2);
switch($$->val.ctype){
case CTINT:
mpnegfix($$.u.xval);
mpnegfix($$->val.u.xval);
break;
case CTFLT:
mpnegflt($$.u.fval);
mpnegflt($$->val.u.fval);
break;
default:
yyerror("bad negated constant");
......@@ -1994,11 +1992,11 @@ hidden_constant:
}
| LTRUE
{
$$ = booltrue->val;
$$ = nodbool(1);
}
| LFALSE
{
$$ = boolfalse->val;
$$ = nodbool(0);
}
hidden_importsym:
......
......@@ -58,7 +58,6 @@ mainlex(int argc, char *argv[])
fmtinstall('L', Lconv); // line number
fmtinstall('B', Bconv); // big numbers
fmtinstall('F', Fconv); // big float numbers
fmtinstall('W', Wconv); // whatis numbers (Wlitint)
lexinit();
lineno = 1;
......@@ -115,13 +114,14 @@ usage:
print("flags:\n");
print(" -I DIR search for packages in DIR\n");
print(" -d print declarations\n");
print(" -e no limit on number of errors printed\n");
print(" -f print stack frame structure\n");
print(" -h panic on an error\n");
print(" -k name specify package name\n");
print(" -o file specify output file\n");
print(" -p print the assembly language\n");
print(" -w print the parse tree after typing\n");
print(" -x print lex tokens\n");
print(" -h panic on an error\n");
myexit(0);
return 0;
}
......@@ -1276,20 +1276,12 @@ lexinit(void)
/* for walk to use in error messages */
types[TFUNC] = functype(N, N, N);
/* types used in front end */
types[TNIL] = typ(TNIL);
types[TIDEAL] = typ(TIDEAL);
/* pick up the backend typedefs */
belexinit(LBASETYPE);
booltrue = nod(OLITERAL, N, N);
booltrue->val.u.bval = 1;
booltrue->val.ctype = CTBOOL;
booltrue->type = types[TBOOL];
booltrue->addable = 1;
boolfalse = nod(OLITERAL, N, N);
boolfalse->val.u.bval = 0;
boolfalse->val.ctype = CTBOOL;
boolfalse->type = types[TBOOL];
boolfalse->addable = 1;
}
struct
......
......@@ -154,10 +154,22 @@ mpmovefixflt(Mpflt *a, Mpint *b)
mpnorm(a);
}
void
// convert (truncate) b to a.
// return -1 (but still convert) if b was non-integer.
int
mpmovefltfix(Mpint *a, Mpflt *b)
{
mpmovecfix(a, mpgetflt(b));
Mpflt f;
*a = b->val;
mpshiftfix(a, b->exp);
if(b->exp < 0) {
f.val = *a;
f.exp = 0;
mpnorm(&f);
if(mpcmpfltflt(b, &f) != 0)
return -1;
}
return 0;
}
void
......@@ -303,7 +315,7 @@ bad:
//
// fixed point input
// required syntax is [+-][0[x]]d*
//
//
void
mpatofix(Mpint *a, char *as)
{
......@@ -422,8 +434,20 @@ Fconv(Fmt *fp)
{
char buf[500];
Mpflt *fvp, fv;
double d;
fvp = va_arg(fp->args, Mpflt*);
if(fp->flags & FmtSharp) {
// alternate form - decimal for error messages.
// for well in range, convert to double and use print's %g
if(-900 < fvp->exp && fvp->exp < 900) {
d = mpgetflt(fvp);
return fmtprint(fp, "%g", d);
}
// TODO(rsc): for well out of range, print
// an approximation like 1.234e1000
}
if(sigfig(fvp) == 0) {
snprint(buf, sizeof(buf), "0p+0");
goto out;
......
......@@ -159,6 +159,7 @@ mpneg(Mpint *a)
}
}
// shift left by s (or right by -s)
void
mpshiftfix(Mpint *a, int s)
{
......
......@@ -29,7 +29,7 @@ yyerror(char *fmt, ...)
*(int*)0 = 0;
nerrors++;
if(nerrors >= 10)
if(nerrors >= 10 && !debug['e'])
fatal("too many errors");
}
......@@ -351,7 +351,7 @@ dobad(void)
}
Node*
nodintconst(int32 v)
nodintconst(int64 v)
{
Node *c;
......@@ -360,11 +360,34 @@ nodintconst(int32 v)
c->val.u.xval = mal(sizeof(*c->val.u.xval));
mpmovecfix(c->val.u.xval, v);
c->val.ctype = CTINT;
c->type = types[TINT];
c->type = types[TIDEAL];
ullmancalc(c);
return c;
}
Node*
nodnil(void)
{
Node *c;
c = nodintconst(0);
c->val.ctype = CTNIL;
c->type = types[TNIL];
return c;
}
Node*
nodbool(int b)
{
Node *c;
c = nodintconst(0);
c->val.ctype = CTBOOL;
c->val.u.bval = b;
c->type = types[TBOOL];
return c;
}
Node*
rev(Node *na)
{
......@@ -437,19 +460,17 @@ aindex(Node *b, Type *t)
bound = -1; // open bound
walktype(b, Erv);
switch(whatis(b)) {
default: // variable bound
yyerror("array bound must be an integer expression");
break;
case Wnil: // open bound
break;
case Wlitint: // fixed bound
bound = mpgetfix(b->val.u.xval);
if(bound < 0)
yyerror("array bound must be non negative");
break;
if(b != nil) {
switch(consttype(b)) {
default:
yyerror("array bound must be an integer expression");
break;
case CTINT:
bound = mpgetfix(b->val.u.xval);
if(bound < 0)
yyerror("array bound must be non negative");
break;
}
}
// fixed array
......@@ -569,64 +590,6 @@ dump(char *s, Node *n)
dodump(n, 1);
}
int
whatis(Node *n)
{
Type *t;
if(n == N)
return Wnil;
if(n->op == OLITERAL) {
switch(n->val.ctype) {
default:
break;
case CTINT:
case CTSINT:
case CTUINT:
return Wlitint;
case CTFLT:
return Wlitfloat;
case CTBOOL:
return Wlitbool;
case CTSTR:
return Wlitstr;
case CTNIL:
return Wlitnil; // not used
}
return Wtunkn;
}
t = n->type;
if(t == T)
return Wtnil;
switch(t->etype) {
case TINT:
case TINT8:
case TINT16:
case TINT32:
case TINT64:
case TUINT:
case TUINT8:
case TUINT16:
case TUINT32:
case TUINT64:
case TUINTPTR:
return Wtint;
case TFLOAT:
case TFLOAT32:
case TFLOAT64:
case TFLOAT80:
return Wtfloat;
case TBOOL:
return Wtbool;
case TSTRING:
return Wtstr;
}
return Wtunkn;
}
/*
s%,%,\n%g
s%\n+%\n%g
......@@ -1013,6 +976,8 @@ basicnames[] =
[TANY] = "any",
[TDDD] = "...",
[TSTRING] = "string",
[TNIL] = "nil",
[TIDEAL] = "ideal",
};
int
......@@ -1302,8 +1267,6 @@ Nconv(Fmt *fp)
snprint(buf1, sizeof(buf1), "LITERAL-ctype=%d", n->val.ctype);
break;
case CTINT:
case CTSINT:
case CTUINT:
snprint(buf1, sizeof(buf1), "I%B", n->val.u.xval);
break;
case CTFLT:
......@@ -1363,7 +1326,7 @@ treecopy(Node *n)
case OLITERAL:
if(n->iota) {
m = literal(iota);
m = nodintconst(iota);
break;
}
m = nod(OXXX, N, N);
......@@ -1416,34 +1379,6 @@ Zconv(Fmt *fp)
return 0;
}
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)
{
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)
{
......@@ -2043,18 +1978,6 @@ ptrto(Type *t)
return t1;
}
Node*
literal(int32 v)
{
Node *n;
n = nod(OLITERAL, N, N);
n->val.u.xval = mal(sizeof(*n->val.u.xval));
n->val.ctype = CTINT;
mpmovecfix(n->val.u.xval, v);
return n;
}
void
frame(int context)
{
......
......@@ -448,7 +448,7 @@ walkswitch(Node *sw)
*/
walkstate(sw->ninit);
if(sw->ntest == N)
sw->ntest = booltrue;
sw->ntest = nodbool(1);
casebody(sw);
/*
......@@ -466,7 +466,7 @@ walkswitch(Node *sw)
return;
}
arg = Snorm;
if(whatis(sw->ntest) == Wlitbool) {
if(isconst(sw->ntest, CTBOOL)) {
arg = Strue;
if(sw->ntest->val.u.xval == 0)
arg = Sfalse;
......@@ -523,10 +523,10 @@ iscaseconst(Node *t)
{
if(t == N || t->left == N)
return 0;
switch(whatis(t->left)) {
case Wlitfloat:
case Wlitint:
case Wlitstr:
switch(consttype(t->left)) {
case CTFLT:
case CTINT:
case CTSTR:
return 1;
}
return 0;
......@@ -616,19 +616,23 @@ csort(Case *l, int(*f)(Case*, Case*))
int
casecmp(Case *c1, Case *c2)
{
int w;
int ct;
Node *n1, *n2;
w = whatis(c1->node->left);
if(w != whatis(c2->node->left))
n1 = c1->node->left;
n2 = c2->node->left;
ct = n1->val.ctype;
if(ct != n2->val.ctype)
fatal("casecmp1");
switch(w) {
case Wlitfloat:
return mpcmpfltflt(c1->node->left->val.u.fval, c2->node->left->val.u.fval);
case Wlitint:
return mpcmpfixfix(c1->node->left->val.u.xval, c2->node->left->val.u.xval);
case Wlitstr:
return cmpslit(c1->node->left, c2->node->left);
switch(ct) {
case CTFLT:
return mpcmpfltflt(n1->val.u.fval, n2->val.u.fval);
case CTINT:
return mpcmpfixfix(n1->val.u.xval, n2->val.u.xval);
case CTSTR:
return cmpslit(n1, n2);
}
fatal("casecmp2");
......
This diff is collapsed.
......@@ -235,7 +235,7 @@ func str(val int64) string { // do it here rather than with fmt to avoid depend
}
func Errstr(errno int64) string {
if errno < 0 || errno >= len(error) {
if errno < 0 || errno >= int64(len(error)) {
return "Error " + str(errno)
}
return error[errno]
......
......@@ -285,7 +285,7 @@ func str(val int64) string { // do it here rather than with fmt to avoid depend
}
func Errstr(errno int64) string {
if errno < 0 || errno >= len(error) {
if errno < 0 || errno >= int64(len(error)) {
return "Error " + str(errno)
}
return error[errno]
......
......@@ -14,6 +14,9 @@ const (
c1 = chuge >> 100;
c3div2 = 3/2;
c1e3 = 1e3;
ctrue = true;
cfalse = !ctrue;
)
const (
......@@ -111,4 +114,7 @@ func floats() {
func main() {
ints();
floats();
assert(ctrue == true, "ctrue == true");
assert(cfalse == false, "cfalse == false");
}
// errchk $G -e $F.go
// Copyright 2009 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
type I interface {}
const (
// assume all types behave similarly to int8/uint8
Int8 int8 = 101;
Minus1 int8 = -1;
Uint8 uint8 = 102;
Const = 103;
Float32 float32 = 104.5;
Float float = 105.5;
ConstFloat = 106.5;
Big float64 = 1e300;
String = "abc";
Bool = true;
)
var (
a1 = Int8 * 100; // ERROR "overflows"
a2 = Int8 * -1; // OK
a3 = Int8 * 1000; // ERROR "overflows"
a4 = Int8 * int8(1000); // ERROR "overflows"
a5 = int8(Int8 * 1000); // ERROR "overflows"
a6 = int8(Int8 * int8(1000)); // ERROR "overflows"
a7 = Int8 - 2*Int8 - 2*Int8; // ERROR "overflows"
a8 = Int8 * Const / 100; // ERROR "overflows"
a9 = Int8 * (Const / 100); // OK
b1 = Uint8 * Uint8; // ERROR "overflows"
b2 = Uint8 * -1; // ERROR "overflows"
b3 = Uint8 - Uint8; // OK
b4 = Uint8 - Uint8 - Uint8; // ERROR "overflows"
b5 = uint8(^0); // ERROR "overflows"
b6 = ^uint8(0); // ERROR "overflows"
b7 = uint8(Minus1); // ERROR "overflows"
b8 = uint8(int8(-1)); // ERROR "overflows"
b8a = uint8(-1); // ERROR "overflows"
b9 byte = (1<<10) >> 8; // OK
b10 byte = (1<<10); // ERROR "overflows"
b11 byte = (byte(1)<<10) >> 8; // ERROR "overflows"
b12 byte = 1000; // ERROR "overflows"
b13 byte = byte(1000); // ERROR "overflows"
b14 byte = byte(100) * byte(100); // ERROR "overflows"
b15 byte = byte(100) * 100; // ERROR "overflows"
b16 byte = byte(0) * 1000; // ERROR "overflows"
b16a byte = 0 * 1000; // OK
b17 byte = byte(0) * byte(1000); // ERROR "overflows"
b18 byte = Uint8/0; // ERROR "division by zero"
c1 float64 = Big;
c2 float64 = Big*Big; // ERROR "overflows"
c3 float64 = float64(Big)*Big; // ERROR "overflows"
c4 = Big*Big; // ERROR "overflows"
c5 = Big/0; // ERROR "division by zero"
)
func f(int);
func main() {
f(Int8); // ERROR "convert"
f(Minus1); // ERROR "convert"
f(Uint8); // ERROR "convert"
f(Const); // OK
f(Float32); // ERROR "convert"
f(Float); // ERROR "convert"
f(ConstFloat); // ERROR "truncate"
f(ConstFloat - 0.5); // OK
f(Big); // ERROR "convert"
f(String); // ERROR "convert"
f(Bool); // ERROR "convert"
}
// errchk $G $D/$F.go
// Copyright 2009 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
const (
A int = 1;
B byte; // ERROR "type without expr"
)
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 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
import "fmt"
type T int
func (t T) String() string {
return fmt.Sprintf("T%d", t);
}
const (
A T = 1<<(1<<iota);
B;
C;
D;
E;
)
func main() {
s := fmt.Sprintf("%v %v %v %v %v", A, B, C, D, E);
if s != "T2 T4 T16 T256 T65536" {
panicln("type info didn't propagate in const: got", s);
}
}
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 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
import "unsafe"
func typeof(x interface{}) string {
val, typ, indir := sys.Reflect(x);
return typ;
}
func f() int {
return 0;
}
func g() int {
return 0;
}
type T func() int
var m = map[string] T {
"f": f
}
type A int
type B int
var a A = 1;
var b B = 2;
var x int;
func main() {
want := typeof(g);
if t := typeof(f); t != want {
panicln("type of f is", t, "want", want);
}
want = typeof(x);
if t := typeof(+a); t != want {
panicln("type of +a is", t, "want", want);
}
if t := typeof(a+0); t != want {
panicln("type of a+0 is", t, "want", want);
}
if t := typeof(a+b); t != want {
panicln("type of a+b is", t, "want", want);
}
}
......@@ -4,6 +4,8 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// ! errchk $G -e $D/$F.go
package main
// explicit conversions are okay, even if they overflow
......@@ -20,10 +22,10 @@ var s string;
var bad1 string = 1; // ERROR "conver|incompatible"
var bad2 = s + 1; // ERROR "conver|incompatible"
var bad3 = s + 'a'; // ERROR "conver|incompatible"
var bad4 = "a" + 1; // ERROR "literals|incompatible"
var bad5 = "a" + 'a'; // ERROR "literals|incompatible"
var bad4 = "a" + 1; // ERROR "literals|incompatible|convert"
var bad5 = "a" + 'a'; // ERROR "literals|incompatible|convert"
var bad6 int = 1.5; // ERROR "convert"
var bad6 int = 1.5; // ERROR "convert|truncate"
var bad7 int = 1e100; // ERROR "overflow"
var bad8 float32 = 1e200; // ERROR "overflow"
......
......@@ -63,11 +63,11 @@ pr -n -t $SOURCEFILE | grep '// ERROR' | while read line; do
mv -f $TMPTMP $TMPALL
if test -z "$errmsg"; then
bug
echo 1>&2 "errchk: $SOURCEFILE: missing expected error message on line $lineno: '$regexp'"
echo 1>&2 "errchk: $SOURCEFILE:$lineno: missing expected error: '$regexp'"
echo 1 > $TMPSTAT
elif ! echo "$errmsg" | egrep -q "$regexp"; then
bug
echo 1>&2 "errchk: $SOURCEFILE: error message on line $lineno does not match '$regexp'"
echo 1>&2 "errchk: $SOURCEFILE:$lineno: error message does not match '$regexp'"
echo 1>&2 $errmsg
echo 1 > $TMPSTAT
fi
......
......@@ -33,13 +33,14 @@ func main() {
f = f3div2;
assert(f == f3div2, "f == f3div2");
i = f3div2; // BUG: probably shouldn't compile
i = f3div2; // ERROR "truncate"
assert(i == c3div2, "i == c3div2 from f3div2");
assert(i != f3div2, "i != f3div2"); // BUG: certainly shouldn't fail
assert(i != f3div2, "i != f3div2"); // ERROR "truncate"
const g float64 = 1.0;
i = g; // BUG: shouldn't compile
i = g; // ERROR "convert"
const h float64 = 3.14;
i = h; // BUG: certainly shouldn't compile
i = h; // ERROR "convert"
i = int(h); // ERROR "truncate"
}
......@@ -7,6 +7,6 @@
package main
func main() {
var x int64 = 0;
println(x != nil); // ERROR "illegal|incompatible"
println(0 != nil); // ERROR "illegal|incompatible"
println(x != nil); // ERROR "illegal|incompatible|nil constant"
println(0 != nil); // ERROR "illegal|incompatible|nil constant"
}
......@@ -32,17 +32,12 @@ pc: xxx
=========== ./convlit.go
BUG: errchk: ./convlit.go: missing expected error message on line 16: 'conver|incompatible'
errchk: ./convlit.go: missing expected error message on line 22: 'convert'
errchk: ./convlit.go: missing expected error message on line 23: 'overflow'
errchk: ./convlit.go: missing expected error message on line 24: 'overflow'
errchk: ./convlit.go: unmatched error messages:
BUG: errchk: ./convlit.go: unmatched error messages:
==================================================
./convlit.go:8: cannot convert non-integer constant to int
./convlit.go:11: overflow converting constant to int
./convlit.go:12: overflow converting constant to float
./convlit.go:8: cannot convert non-integer constant to int
./convlit.go:8: fatal error: too many errors
./convlit.go:8: constant 1.5 truncated to integer
./convlit.go:11: constant 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 overflows int
./convlit.go:12: constant 34911850510716223476646871064527264675788468424693128821036252992306087892081078460155404277013793117885253p+2968 overflows float
./convlit.go:9: constant 1.5 truncated to integer
==================================================
=========== ./helloworld.go
......@@ -116,7 +111,7 @@ bugs/bug108.go:4: stupid shift: 1025
BUG: errchk: command succeeded unexpectedly: 6g bugs/bug108.go
=========== bugs/bug115.go
bugs/bug115.go:8: overflow converting constant to uint
bugs/bug115.go:8: constant -1 overflows uint
BUG: bug115 should compile
=========== bugs/bug117.go
......@@ -129,7 +124,9 @@ BUG: should compile
BUG: errchk: command succeeded unexpectedly: 6g bugs/bug125.go
=========== bugs/bug131.go
BUG: should not compile
bugs/bug131.go:7: cannot convert uint64 constant to int64
bugs/bug131.go:7: illegal types for operand: AS
int64
=========== bugs/bug132.go
BUG: compilation succeeds incorrectly
......@@ -138,12 +135,11 @@ BUG: compilation succeeds incorrectly
BUG: should not compile
=========== bugs/bug138.go
bugs/bug138.go:8: overflow converting constant to uint
bugs/bug138.go:8: illegal combination of literals CONV 7
bugs/bug138.go:8: constant -1 overflows uint
BUG should compile
=========== fixedbugs/bug016.go
fixedbugs/bug016.go:7: overflow converting constant to uint
fixedbugs/bug016.go:7: constant -3 overflows uint
=========== fixedbugs/bug027.go
hi
......@@ -177,7 +173,7 @@ fixedbugs/bug039.go:6: variable x redeclared in this block
fixedbugs/bug041.go:5: export of incomplete type t
=========== fixedbugs/bug049.go
fixedbugs/bug049.go:6: illegal conversion of nil to string
fixedbugs/bug049.go:6: cannot convert nil constant to string
=========== fixedbugs/bug050.go
fixedbugs/bug050.go:3: package statement must be first
......@@ -187,7 +183,7 @@ sys.6:1 fixedbugs/bug050.go:3: syntax error near package
fixedbugs/bug051.go:10: expression must be a constant
=========== fixedbugs/bug062.go
fixedbugs/bug062.go:6: illegal conversion of nil to string
fixedbugs/bug062.go:6: cannot convert nil constant to string
fixedbugs/bug062.go:6: illegal types for operand: AS
string
......@@ -210,9 +206,13 @@ fixedbugs/bug072.go:6: bug: undefined
fixedbugs/bug073.go:8: illegal types for operand: LSH
int
int
fixedbugs/bug073.go:8: illegal types for operand: AS
int
fixedbugs/bug073.go:9: illegal types for operand: RSH
int
int
fixedbugs/bug073.go:9: illegal types for operand: AS
int
=========== fixedbugs/bug074.go
fixedbugs/bug074.go:6: invalid type for composite literal: string
......@@ -227,18 +227,6 @@ fixedbugs/bug083.dir/bug1.go:9: syntax error near t0
=========== fixedbugs/bug086.go
fixedbugs/bug086.go:5: function ends without a return statement
=========== fixedbugs/bug090.go
fixedbugs/bug090.go:32: cannot convert non-integer constant to int
fixedbugs/bug090.go:32: illegal types for operand: AS
int
fixedbugs/bug090.go:34: cannot convert non-integer constant to int
fixedbugs/bug090.go:34: illegal types for operand: CALL
bool
fixedbugs/bug090.go:40: cannot convert non-integer constant to int
fixedbugs/bug090.go:40: illegal types for operand: AS
int
float64
=========== fixedbugs/bug091.go
fixedbugs/bug091.go:15: c: undefined
fixedbugs/bug091.go:15: illegal types for operand: AS
......
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