Skip to content

Commit

Permalink
gc: five bug fixes, one better error.
Browse files Browse the repository at this point in the history
* check for struct literal assignment to private fields.
* record, fix crash involving parallel map assignment.
* avoid infinite recursion in exportassignok.
* make floating point bounds check precise.
* avoid crash on invalid receiver.

* add context to error about implicit assignment.

Fixes #86.
Fixes #88.
Fixes #158.
Fixes #174.
Fixes #201.
Fixes #204.

R=ken2
https://golang.org/cl/154144
  • Loading branch information
rsc committed Nov 15, 2009
1 parent a967f57 commit a338231
Show file tree
Hide file tree
Showing 17 changed files with 246 additions and 65 deletions.
9 changes: 5 additions & 4 deletions src/cmd/gc/align.c
Expand Up @@ -495,10 +495,11 @@ typeinit(void)
mpatofix(maxintval[TUINT32], "0xffffffff");
mpatofix(maxintval[TUINT64], "0xffffffffffffffff");

mpatoflt(maxfltval[TFLOAT32], "3.40282347e+38");
mpatoflt(minfltval[TFLOAT32], "-3.40282347e+38");
mpatoflt(maxfltval[TFLOAT64], "1.7976931348623157e+308");
mpatoflt(minfltval[TFLOAT64], "-1.7976931348623157e+308");
/* f is valid float if min < f < max. (min and max are not themselves valid.) */
mpatoflt(maxfltval[TFLOAT32], "33554431p103"); /* 2^24-1 p (127-23) + 1/2 ulp*/
mpatoflt(minfltval[TFLOAT32], "-33554431p103");
mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970"); /* 2^53-1 p (1023-52) + 1/2 ulp */
mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970");

/* for walk to use in error messages */
types[TFUNC] = functype(N, nil, nil);
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/gc/const.c
Expand Up @@ -261,8 +261,8 @@ overflow(Val v, Type *t)
case CTFLT:
if(!isfloat[t->etype])
fatal("overflow: %T floating-point constant", t);
if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) < 0
|| mpcmpfltflt(v.u.fval, maxfltval[t->etype]) > 0)
if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) <= 0
|| mpcmpfltflt(v.u.fval, maxfltval[t->etype]) >= 0)
yyerror("constant %#F overflows %T", v.u.fval, t);
break;
}
Expand Down
18 changes: 17 additions & 1 deletion src/cmd/gc/dcl.c
Expand Up @@ -302,11 +302,27 @@ NodeList*
variter(NodeList *vl, Node *t, NodeList *el)
{
int doexpr;
Node *v, *e;
Node *v, *e, *as2;
NodeList *init;

init = nil;
doexpr = el != nil;

if(count(el) == 1 && count(vl) > 1) {
e = el->n;
as2 = nod(OAS2, N, N);
as2->list = vl;
as2->rlist = list1(e);
for(; vl; vl=vl->next) {
v = vl->n;
v->op = ONAME;
declare(v, dclcontext);
v->ntype = t;
v->defn = as2;
}
return list1(as2);
}

for(; vl; vl=vl->next) {
if(doexpr) {
if(el == nil) {
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/gc/go.h
Expand Up @@ -1048,8 +1048,8 @@ void typechecklist(NodeList*, int);
void typecheckswitch(Node*);
void typecheckselect(Node*);
void typecheckrange(Node*);
Node* typecheckconv(Node*, Node*, Type*, int);
int checkconv(Type*, Type*, int, int*, int*);
Node* typecheckconv(Node*, Node*, Type*, int, char*);
int checkconv(Type*, Type*, int, int*, int*, char*);
Node* typecheck(Node**, int);

/*
Expand Down
15 changes: 13 additions & 2 deletions src/cmd/gc/go.y
Expand Up @@ -1087,6 +1087,8 @@ xfndcl:
LFUNC fndcl fnbody
{
$$ = $2;
if($$ == N)
break;
$$->nbody = $3;
funcbody($$);
}
Expand All @@ -1111,10 +1113,19 @@ fndcl:
{
Node *rcvr, *t;

$$ = N;
if($2 == nil) {
yyerror("method has no receiver");
break;
}
if($2->next != nil) {
yyerror("method has multiple receivers");
break;
}
rcvr = $2->n;
if($2->next != nil || $2->n->op != ODCLFIELD) {
if(rcvr->op != ODCLFIELD) {
yyerror("bad receiver in method");
rcvr = N;
break;
}

$$ = nod(ODCLFUNC, N, N);
Expand Down
12 changes: 10 additions & 2 deletions src/cmd/gc/obj.c
Expand Up @@ -114,6 +114,7 @@ ieeedtod(uint64 *ieee, double native)
double fr, ho, f;
int exp;
uint32 h, l;
uint64 bits;

if(native < 0) {
ieeedtod(ieee, -native);
Expand All @@ -129,13 +130,20 @@ ieeedtod(uint64 *ieee, double native)
fr = modf(fr*f, &ho);
h = ho;
h &= 0xfffffL;
h |= (exp+1022L) << 20;
f = 65536L;
fr = modf(fr*f, &ho);
l = ho;
l <<= 16;
l |= (int32)(fr*f);
*ieee = ((uint64)h << 32) | l;
bits = ((uint64)h<<32) | l;
if(exp < -1021) {
// gradual underflow
bits |= 1LL<<52;
bits >>= -1021 - exp;
exp = -1022;
}
bits |= (uint64)(exp+1022L) << 52;
*ieee = bits;
}

int
Expand Down
4 changes: 2 additions & 2 deletions src/cmd/gc/range.c
Expand Up @@ -66,12 +66,12 @@ typecheckrange(Node *n)

if(v1->defn == n)
v1->type = t1;
else if(v1->type != T && checkconv(t1, v1->type, 0, &op, &et) < 0)
else if(v1->type != T && checkconv(t1, v1->type, 0, &op, &et, "range") < 0)
yyerror("cannot assign type %T to %+N", t1, v1);
if(v2) {
if(v2->defn == n)
v2->type = t2;
else if(v2->type != T && checkconv(t2, v2->type, 0, &op, &et) < 0)
else if(v2->type != T && checkconv(t2, v2->type, 0, &op, &et, "range") < 0)
yyerror("cannot assign type %T to %+N", t1, v1);
}

Expand Down
6 changes: 6 additions & 0 deletions src/cmd/gc/sinit.c
Expand Up @@ -59,6 +59,12 @@ init1(Node *n, NodeList **out)
print("%S\n", n->sym);
*out = list(*out, n->defn);
break;

case OAS2FUNC:
for(l=n->defn->rlist; l; l=l->next)
init1(l->n, out);
*out = list(*out, n->defn);
break;
}
}
n->initorder = 1;
Expand Down

0 comments on commit a338231

Please sign in to comment.