mirror of
https://github.com/golang/go
synced 2024-11-24 23:07:56 -07:00
gc: implement character constant type rules
R=ken2 CC=golang-dev https://golang.org/cl/5444054
This commit is contained in:
parent
2065b0a094
commit
be0ffbfd02
@ -1066,7 +1066,7 @@ bgen(Node *n, int true, Prog *to)
|
||||
}
|
||||
|
||||
if(nr->op == OLITERAL) {
|
||||
if(nr->val.ctype == CTINT && mpgetfix(nr->val.u.xval) == 0) {
|
||||
if(isconst(nr, CTINT) && mpgetfix(nr->val.u.xval) == 0) {
|
||||
gencmp0(nl, nl->type, a, to);
|
||||
break;
|
||||
}
|
||||
|
@ -1320,6 +1320,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
||||
a->dval = mpgetflt(n->val.u.fval);
|
||||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
a->sym = S;
|
||||
a->type = D_CONST;
|
||||
a->offset = mpgetfix(n->val.u.xval);
|
||||
@ -1777,7 +1778,7 @@ sudoaddable(int as, Node *n, Addr *a, int *w)
|
||||
|
||||
switch(n->op) {
|
||||
case OLITERAL:
|
||||
if(n->val.ctype != CTINT)
|
||||
if(!isconst(n, CTINT))
|
||||
break;
|
||||
v = mpgetfix(n->val.u.xval);
|
||||
if(v >= 32000 || v <= -32000)
|
||||
|
@ -1175,6 +1175,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
||||
a->dval = mpgetflt(n->val.u.fval);
|
||||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
a->sym = S;
|
||||
a->type = D_CONST;
|
||||
a->offset = mpgetfix(n->val.u.xval);
|
||||
@ -1878,7 +1879,7 @@ sudoaddable(int as, Node *n, Addr *a)
|
||||
|
||||
switch(n->op) {
|
||||
case OLITERAL:
|
||||
if(n->val.ctype != CTINT)
|
||||
if(!isconst(n, CTINT))
|
||||
break;
|
||||
v = mpgetfix(n->val.u.xval);
|
||||
if(v >= 32000 || v <= -32000)
|
||||
|
@ -1885,6 +1885,7 @@ naddr(Node *n, Addr *a, int canemitcode)
|
||||
a->dval = mpgetflt(n->val.u.fval);
|
||||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
a->sym = S;
|
||||
a->type = D_CONST;
|
||||
a->offset = mpgetfix(n->val.u.xval);
|
||||
|
@ -170,6 +170,7 @@ convlit1(Node **np, Type *t, int explicit)
|
||||
break;
|
||||
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
case CTFLT:
|
||||
case CTCPLX:
|
||||
ct = n->val.ctype;
|
||||
@ -179,6 +180,7 @@ convlit1(Node **np, Type *t, int explicit)
|
||||
goto bad;
|
||||
case CTCPLX:
|
||||
case CTFLT:
|
||||
case CTRUNE:
|
||||
n->val = toint(n->val);
|
||||
// flowthrough
|
||||
case CTINT:
|
||||
@ -192,6 +194,7 @@ convlit1(Node **np, Type *t, int explicit)
|
||||
goto bad;
|
||||
case CTCPLX:
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
n->val = toflt(n->val);
|
||||
// flowthrough
|
||||
case CTFLT:
|
||||
@ -206,6 +209,7 @@ convlit1(Node **np, Type *t, int explicit)
|
||||
goto bad;
|
||||
case CTFLT:
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
n->val = tocplx(n->val);
|
||||
break;
|
||||
case CTCPLX:
|
||||
@ -213,7 +217,7 @@ convlit1(Node **np, Type *t, int explicit)
|
||||
break;
|
||||
}
|
||||
} else
|
||||
if(et == TSTRING && ct == CTINT && explicit)
|
||||
if(et == TSTRING && (ct == CTINT || ct == CTRUNE) && explicit)
|
||||
n->val = tostr(n->val);
|
||||
else
|
||||
goto bad;
|
||||
@ -243,6 +247,7 @@ copyval(Val v)
|
||||
|
||||
switch(v.ctype) {
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
i = mal(sizeof(*i));
|
||||
mpmovefixfix(i, v.u.xval);
|
||||
v.u.xval = i;
|
||||
@ -269,6 +274,7 @@ tocplx(Val v)
|
||||
|
||||
switch(v.ctype) {
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
c = mal(sizeof(*c));
|
||||
mpmovefixflt(&c->real, v.u.xval);
|
||||
mpmovecflt(&c->imag, 0.0);
|
||||
@ -293,6 +299,7 @@ toflt(Val v)
|
||||
|
||||
switch(v.ctype) {
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
f = mal(sizeof(*f));
|
||||
mpmovefixflt(f, v.u.xval);
|
||||
v.ctype = CTFLT;
|
||||
@ -316,6 +323,9 @@ toint(Val v)
|
||||
Mpint *i;
|
||||
|
||||
switch(v.ctype) {
|
||||
case CTRUNE:
|
||||
v.ctype = CTINT;
|
||||
break;
|
||||
case CTFLT:
|
||||
i = mal(sizeof(*i));
|
||||
if(mpmovefltfix(i, v.u.fval) < 0)
|
||||
@ -345,6 +355,7 @@ overflow(Val v, Type *t)
|
||||
return;
|
||||
switch(v.ctype) {
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
if(!isint[t->etype])
|
||||
fatal("overflow: %T integer constant", t);
|
||||
if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0 ||
|
||||
@ -379,6 +390,7 @@ tostr(Val v)
|
||||
|
||||
switch(v.ctype) {
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
if(mpcmpfixfix(v.u.xval, minintval[TINT]) < 0 ||
|
||||
mpcmpfixfix(v.u.xval, maxintval[TINT]) > 0)
|
||||
yyerror("overflow in int -> string");
|
||||
@ -415,7 +427,12 @@ consttype(Node *n)
|
||||
int
|
||||
isconst(Node *n, int ct)
|
||||
{
|
||||
return consttype(n) == ct;
|
||||
int t;
|
||||
|
||||
t = consttype(n);
|
||||
// If the caller is asking for CTINT, allow CTRUNE too.
|
||||
// Makes life easier for back ends.
|
||||
return t == ct || (ct == CTINT && t == CTRUNE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -518,7 +535,8 @@ evconst(Node *n)
|
||||
n->right = nr;
|
||||
if(nr->type && (issigned[nr->type->etype] || !isint[nr->type->etype]))
|
||||
goto illegal;
|
||||
nl->val = toint(nl->val);
|
||||
if(nl->val.ctype != CTRUNE)
|
||||
nl->val = toint(nl->val);
|
||||
nr->val = toint(nr->val);
|
||||
break;
|
||||
}
|
||||
@ -540,6 +558,17 @@ evconst(Node *n)
|
||||
v = toflt(v);
|
||||
rv = toflt(rv);
|
||||
}
|
||||
|
||||
// Rune and int turns into rune.
|
||||
if(v.ctype == CTRUNE && rv.ctype == CTINT)
|
||||
rv.ctype = CTRUNE;
|
||||
if(v.ctype == CTINT && rv.ctype == CTRUNE) {
|
||||
if(n->op == OLSH || n->op == ORSH)
|
||||
rv.ctype = CTINT;
|
||||
else
|
||||
v.ctype = CTRUNE;
|
||||
}
|
||||
|
||||
if(v.ctype != rv.ctype) {
|
||||
// Use of undefined name as constant?
|
||||
if((v.ctype == 0 || rv.ctype == 0) && nerrors > 0)
|
||||
@ -559,15 +588,19 @@ evconst(Node *n)
|
||||
return;
|
||||
|
||||
case TUP(OADD, CTINT):
|
||||
case TUP(OADD, CTRUNE):
|
||||
mpaddfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(OSUB, CTINT):
|
||||
case TUP(OSUB, CTRUNE):
|
||||
mpsubfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(OMUL, CTINT):
|
||||
case TUP(OMUL, CTRUNE):
|
||||
mpmulfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(ODIV, CTINT):
|
||||
case TUP(ODIV, CTRUNE):
|
||||
if(mpcmpfixc(rv.u.xval, 0) == 0) {
|
||||
yyerror("division by zero");
|
||||
mpmovecfix(v.u.xval, 1);
|
||||
@ -576,6 +609,7 @@ evconst(Node *n)
|
||||
mpdivfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(OMOD, CTINT):
|
||||
case TUP(OMOD, CTRUNE):
|
||||
if(mpcmpfixc(rv.u.xval, 0) == 0) {
|
||||
yyerror("division by zero");
|
||||
mpmovecfix(v.u.xval, 1);
|
||||
@ -585,21 +619,27 @@ evconst(Node *n)
|
||||
break;
|
||||
|
||||
case TUP(OLSH, CTINT):
|
||||
case TUP(OLSH, CTRUNE):
|
||||
mplshfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(ORSH, CTINT):
|
||||
case TUP(ORSH, CTRUNE):
|
||||
mprshfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(OOR, CTINT):
|
||||
case TUP(OOR, CTRUNE):
|
||||
mporfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(OAND, CTINT):
|
||||
case TUP(OAND, CTRUNE):
|
||||
mpandfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(OANDNOT, CTINT):
|
||||
case TUP(OANDNOT, CTRUNE):
|
||||
mpandnotfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
case TUP(OXOR, CTINT):
|
||||
case TUP(OXOR, CTRUNE):
|
||||
mpxorfixfix(v.u.xval, rv.u.xval);
|
||||
break;
|
||||
|
||||
@ -649,26 +689,32 @@ evconst(Node *n)
|
||||
goto setfalse;
|
||||
|
||||
case TUP(OEQ, CTINT):
|
||||
case TUP(OEQ, CTRUNE):
|
||||
if(mpcmpfixfix(v.u.xval, rv.u.xval) == 0)
|
||||
goto settrue;
|
||||
goto setfalse;
|
||||
case TUP(ONE, CTINT):
|
||||
case TUP(ONE, CTRUNE):
|
||||
if(mpcmpfixfix(v.u.xval, rv.u.xval) != 0)
|
||||
goto settrue;
|
||||
goto setfalse;
|
||||
case TUP(OLT, CTINT):
|
||||
case TUP(OLT, CTRUNE):
|
||||
if(mpcmpfixfix(v.u.xval, rv.u.xval) < 0)
|
||||
goto settrue;
|
||||
goto setfalse;
|
||||
case TUP(OLE, CTINT):
|
||||
case TUP(OLE, CTRUNE):
|
||||
if(mpcmpfixfix(v.u.xval, rv.u.xval) <= 0)
|
||||
goto settrue;
|
||||
goto setfalse;
|
||||
case TUP(OGE, CTINT):
|
||||
case TUP(OGE, CTRUNE):
|
||||
if(mpcmpfixfix(v.u.xval, rv.u.xval) >= 0)
|
||||
goto settrue;
|
||||
goto setfalse;
|
||||
case TUP(OGT, CTINT):
|
||||
case TUP(OGT, CTRUNE):
|
||||
if(mpcmpfixfix(v.u.xval, rv.u.xval) > 0)
|
||||
goto settrue;
|
||||
goto setfalse;
|
||||
@ -786,17 +832,21 @@ unary:
|
||||
}
|
||||
// fall through
|
||||
case TUP(OCONV, CTINT):
|
||||
case TUP(OCONV, CTRUNE):
|
||||
case TUP(OCONV, CTFLT):
|
||||
case TUP(OCONV, CTSTR):
|
||||
convlit1(&nl, n->type, 1);
|
||||
break;
|
||||
|
||||
case TUP(OPLUS, CTINT):
|
||||
case TUP(OPLUS, CTRUNE):
|
||||
break;
|
||||
case TUP(OMINUS, CTINT):
|
||||
case TUP(OMINUS, CTRUNE):
|
||||
mpnegfix(v.u.xval);
|
||||
break;
|
||||
case TUP(OCOM, CTINT):
|
||||
case TUP(OCOM, CTRUNE):
|
||||
et = Txxx;
|
||||
if(nl->type != T)
|
||||
et = nl->type->etype;
|
||||
@ -889,6 +939,7 @@ nodlit(Val v)
|
||||
n->type = idealbool;
|
||||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
case CTFLT:
|
||||
case CTCPLX:
|
||||
n->type = types[TIDEAL];
|
||||
@ -1008,6 +1059,9 @@ defaultlit(Node **np, Type *t)
|
||||
case CTINT:
|
||||
n->type = types[TINT];
|
||||
goto num;
|
||||
case CTRUNE:
|
||||
n->type = runetype;
|
||||
goto num;
|
||||
case CTFLT:
|
||||
n->type = types[TFLOAT64];
|
||||
goto num;
|
||||
@ -1072,6 +1126,13 @@ defaultlit2(Node **lp, Node **rp, int force)
|
||||
convlit(rp, types[TFLOAT64]);
|
||||
return;
|
||||
}
|
||||
|
||||
if(isconst(l, CTRUNE) || isconst(r, CTRUNE)) {
|
||||
convlit(lp, runetype);
|
||||
convlit(rp, runetype);
|
||||
return;
|
||||
}
|
||||
|
||||
convlit(lp, types[TINT]);
|
||||
convlit(rp, types[TINT]);
|
||||
}
|
||||
@ -1108,7 +1169,7 @@ cmpslit(Node *l, Node *r)
|
||||
int
|
||||
smallintconst(Node *n)
|
||||
{
|
||||
if(n->op == OLITERAL && n->val.ctype == CTINT && n->type != T)
|
||||
if(n->op == OLITERAL && isconst(n, CTINT) && n->type != T)
|
||||
switch(simtype[n->type->etype]) {
|
||||
case TINT8:
|
||||
case TUINT8:
|
||||
@ -1210,6 +1271,7 @@ convconst(Node *con, Type *t, Val *val)
|
||||
default:
|
||||
fatal("convconst ctype=%d %lT", val->ctype, t);
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
i = mpgetfix(val->u.xval);
|
||||
break;
|
||||
case CTBOOL:
|
||||
|
@ -354,12 +354,22 @@ static int
|
||||
Vconv(Fmt *fp)
|
||||
{
|
||||
Val *v;
|
||||
vlong x;
|
||||
|
||||
v = va_arg(fp->args, Val*);
|
||||
|
||||
switch(v->ctype) {
|
||||
case CTINT:
|
||||
return fmtprint(fp, "%B", v->u.xval);
|
||||
case CTRUNE:
|
||||
x = mpgetfix(v->u.xval);
|
||||
if(' ' <= x && x < 0x80)
|
||||
return fmtprint(fp, "'%c'", (int)x);
|
||||
if(0 <= x && x < (1<<16))
|
||||
return fmtprint(fp, "'\\u%04ux'", (int)x);
|
||||
if(0 <= x && x <= Runemax)
|
||||
return fmtprint(fp, "'\\U%08llux'", x);
|
||||
return fmtprint(fp, "('\\x00' + %B)", v->u.xval);
|
||||
case CTFLT:
|
||||
return fmtprint(fp, "%F", v->u.fval);
|
||||
case CTCPLX: // ? 1234i -> (0p+0+617p+1)
|
||||
|
@ -113,7 +113,7 @@ struct Val
|
||||
{
|
||||
short reg; // OREGISTER
|
||||
short bval; // bool value CTBOOL
|
||||
Mpint* xval; // int CTINT
|
||||
Mpint* xval; // int CTINT, rune CTRUNE
|
||||
Mpflt* fval; // float CTFLT
|
||||
Mpcplx* cval; // float CTCPLX
|
||||
Strlit* sval; // string CTSTR
|
||||
@ -527,6 +527,7 @@ enum
|
||||
CTxxx,
|
||||
|
||||
CTINT,
|
||||
CTRUNE,
|
||||
CTFLT,
|
||||
CTCPLX,
|
||||
CTSTR,
|
||||
|
@ -1974,6 +1974,7 @@ hidden_literal:
|
||||
$$ = nodlit($2);
|
||||
switch($$->val.ctype){
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
mpnegfix($$->val.u.xval);
|
||||
break;
|
||||
case CTFLT:
|
||||
@ -1994,6 +1995,11 @@ hidden_constant:
|
||||
hidden_literal
|
||||
| '(' hidden_literal '+' hidden_literal ')'
|
||||
{
|
||||
if($2->val.ctype == CTRUNE && $4->val.ctype == CTINT) {
|
||||
$$ = $2;
|
||||
mpaddfixfix($2->val.u.xval, $4->val.u.xval);
|
||||
break;
|
||||
}
|
||||
$$ = nodcplxlit($2->val, $4->val);
|
||||
}
|
||||
|
||||
|
@ -840,7 +840,7 @@ l0:
|
||||
}
|
||||
yylval.val.u.xval = mal(sizeof(*yylval.val.u.xval));
|
||||
mpmovecfix(yylval.val.u.xval, v);
|
||||
yylval.val.ctype = CTINT;
|
||||
yylval.val.ctype = CTRUNE;
|
||||
DBG("lex: codepoint literal\n");
|
||||
strcpy(litbuf, "string literal");
|
||||
return LLITERAL;
|
||||
|
@ -1341,6 +1341,7 @@ iszero(Node *n)
|
||||
return n->val.u.bval == 0;
|
||||
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
return mpcmpfixc(n->val.u.xval, 0) == 0;
|
||||
|
||||
case CTFLT:
|
||||
|
@ -709,6 +709,7 @@ aindex(Node *b, Type *t)
|
||||
yyerror("array bound must be an integer expression");
|
||||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
bound = mpgetfix(b->val.u.xval);
|
||||
if(bound < 0)
|
||||
yyerror("array bound must be non negative");
|
||||
|
@ -132,6 +132,7 @@ exprcmp(Case *c1, Case *c2)
|
||||
n = mpcmpfltflt(n1->val.u.fval, n2->val.u.fval);
|
||||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
n = mpcmpfixfix(n1->val.u.xval, n2->val.u.xval);
|
||||
break;
|
||||
case CTSTR:
|
||||
@ -380,6 +381,7 @@ mkcaselist(Node *sw, int arg)
|
||||
switch(consttype(n->left)) {
|
||||
case CTFLT:
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
case CTSTR:
|
||||
c->type = Texprconst;
|
||||
}
|
||||
|
@ -257,6 +257,7 @@ reswitch:
|
||||
l = typecheck(&n->left, Erv);
|
||||
switch(consttype(l)) {
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
v = l->val;
|
||||
break;
|
||||
case CTFLT:
|
||||
@ -1849,6 +1850,7 @@ keydup(Node *n, Node *hash[], ulong nhash)
|
||||
b = 23;
|
||||
break;
|
||||
case CTINT:
|
||||
case CTRUNE:
|
||||
b = mpgetfix(n->val.u.xval);
|
||||
break;
|
||||
case CTFLT:
|
||||
|
@ -1538,6 +1538,9 @@ walkprint(Node *nn, NodeList **init, int defer)
|
||||
n = l->n;
|
||||
if(n->op == OLITERAL) {
|
||||
switch(n->val.ctype) {
|
||||
case CTRUNE:
|
||||
defaultlit(&n, runetype);
|
||||
break;
|
||||
case CTINT:
|
||||
defaultlit(&n, types[TINT64]);
|
||||
break;
|
||||
|
43
test/rune.go
Normal file
43
test/rune.go
Normal file
@ -0,0 +1,43 @@
|
||||
// $G $D/$F.go
|
||||
|
||||
// Copyright 2011 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 (
|
||||
r0 = 'a'
|
||||
r1 = 'a'+1
|
||||
r2 = 1+'a'
|
||||
r3 = 'a'*2
|
||||
r4 = 'a'/2
|
||||
r5 = 'a'<<1
|
||||
r6 = 'b'<<2
|
||||
|
||||
r = []rune{r0, r1, r2, r3, r4, r5, r6}
|
||||
)
|
||||
|
||||
var (
|
||||
f0 = 1.2
|
||||
f1 = 1.2/'a'
|
||||
|
||||
f = []float64{f0, f1}
|
||||
)
|
||||
|
||||
var (
|
||||
i0 = 1
|
||||
i1 = 1<<'\x01'
|
||||
|
||||
i = []int{i0, i1}
|
||||
)
|
||||
|
||||
const (
|
||||
maxRune = '\U0010FFFF'
|
||||
)
|
||||
|
||||
var (
|
||||
b0 = maxRune < r0
|
||||
|
||||
b = []bool{b0}
|
||||
)
|
Loading…
Reference in New Issue
Block a user