Commit d40f032d authored by Ken Thompson's avatar Ken Thompson

fixed bug in certain

evaluation of complex literals

R=r
OCL=15036
CL=15036
parent c4748872
...@@ -244,6 +244,9 @@ loop: ...@@ -244,6 +244,9 @@ loop:
continpc = pc; continpc = pc;
gen(n->nincr, L); // contin: incr gen(n->nincr, L); // contin: incr
patch(p1, pc); // test: patch(p1, pc); // test:
if(n->ntest != N)
if(n->ntest->ninit != N)
gen(n->ntest->ninit, L);
bgen(n->ntest, 0, breakpc); // if(!test) goto break bgen(n->ntest, 0, breakpc); // if(!test) goto break
if(labloop != L) { if(labloop != L) {
labloop->op = OFOR; labloop->op = OFOR;
...@@ -261,6 +264,9 @@ loop: ...@@ -261,6 +264,9 @@ loop:
p1 = gbranch(AJMP, T); // goto test p1 = gbranch(AJMP, T); // goto test
p2 = gbranch(AJMP, T); // p2: goto else p2 = gbranch(AJMP, T); // p2: goto else
patch(p1, pc); // test: patch(p1, pc); // test:
if(n->ntest != N)
if(n->ntest->ninit != N)
gen(n->ntest->ninit, L);
bgen(n->ntest, 0, p2); // if(!test) goto p2 bgen(n->ntest, 0, p2); // if(!test) goto p2
gen(n->nbody, L); // then gen(n->nbody, L); // then
p3 = gbranch(AJMP, T); // goto done p3 = gbranch(AJMP, T); // goto done
...@@ -522,6 +528,9 @@ swgen(Node *n) ...@@ -522,6 +528,9 @@ swgen(Node *n)
patch(p1, pc); patch(p1, pc);
if(n->ntest != N)
if(n->ntest->ninit != N)
gen(n->ntest->ninit, L);
tempname(&tmp, n->ntest->type); tempname(&tmp, n->ntest->type);
cgen(n->ntest, &tmp); cgen(n->ntest, &tmp);
......
...@@ -250,7 +250,7 @@ Bvardcl: ...@@ -250,7 +250,7 @@ Bvardcl:
} }
| new_name '=' expr | new_name '=' expr
{ {
walktype($3, Erv); // this is a little harry gettype($3);
defaultlit($3); defaultlit($3);
dodclvar($1, $3->type); dodclvar($1, $3->type);
$$ = nod(OAS, $1, $3); $$ = nod(OAS, $1, $3);
...@@ -260,7 +260,7 @@ constdcl: ...@@ -260,7 +260,7 @@ constdcl:
new_name type '=' expr new_name type '=' expr
{ {
Node *c = treecopy($4); Node *c = treecopy($4);
walktype(c, Erv); gettype(c);
convlit(c, $2); convlit(c, $2);
dodclconst($1, c); dodclconst($1, c);
...@@ -270,7 +270,7 @@ constdcl: ...@@ -270,7 +270,7 @@ constdcl:
| new_name '=' expr | new_name '=' expr
{ {
Node *c = treecopy($3); Node *c = treecopy($3);
walktype(c, Erv); gettype(c);
dodclconst($1, c); dodclconst($1, c);
lastconst = $3; lastconst = $3;
...@@ -282,7 +282,7 @@ constdcl1: ...@@ -282,7 +282,7 @@ constdcl1:
| new_name type | new_name type
{ {
Node *c = treecopy(lastconst); Node *c = treecopy(lastconst);
walktype(c, Erv); gettype(c);
convlit(c, $2); convlit(c, $2);
dodclconst($1, c); dodclconst($1, c);
...@@ -291,7 +291,7 @@ constdcl1: ...@@ -291,7 +291,7 @@ constdcl1:
| new_name | new_name
{ {
Node *c = treecopy(lastconst); Node *c = treecopy(lastconst);
walktype(c, Erv); gettype(c);
dodclconst($1, c); dodclconst($1, c);
iota += 1; iota += 1;
...@@ -346,6 +346,7 @@ noninc_stmt: ...@@ -346,6 +346,7 @@ noninc_stmt:
| expr_list LCOLAS expr_list | expr_list LCOLAS expr_list
{ {
$$ = nod(OAS, colas($1, $3), $3); $$ = nod(OAS, colas($1, $3), $3);
addtotop($$);
} }
| LPRINT '(' oexpr_list ')' | LPRINT '(' oexpr_list ')'
{ {
...@@ -379,23 +380,17 @@ complex_stmt: ...@@ -379,23 +380,17 @@ complex_stmt:
popdcl(); popdcl();
$$ = $2; $$ = $2;
$$->op = OSWITCH; $$->op = OSWITCH;
//if($$->ninit != N && $$->ntest == N)
// yyerror("switch expression should not be missing");
} }
| LIF if_stmt | LIF if_stmt
{ {
popdcl(); popdcl();
$$ = $2; $$ = $2;
//if($$->ninit != N && $$->ntest == N)
// yyerror("if conditional should not be missing");
} }
| LIF if_stmt LELSE else_stmt1 | LIF if_stmt LELSE else_stmt1
{ {
popdcl(); popdcl();
$$ = $2; $$ = $2;
$$->nelse = $4; $$->nelse = $4;
//if($$->ninit != N && $$->ntest == N)
// yyerror("if conditional should not be missing");
} }
| LSELECT select_stmt | LSELECT select_stmt
{ {
...@@ -453,8 +448,6 @@ semi_stmt: ...@@ -453,8 +448,6 @@ semi_stmt:
popdcl(); popdcl();
$$ = $2; $$ = $2;
$$->nelse = $4; $$->nelse = $4;
//if($$->ninit != N && $$->ntest == N)
// yyerror("if conditional should not be missing");
} }
compound_stmt: compound_stmt:
......
...@@ -13,18 +13,48 @@ static Node* addtop; ...@@ -13,18 +13,48 @@ static Node* addtop;
void void
walk(Node *fn) walk(Node *fn)
{ {
if(debug['W']) char s[50];
dump("fn-before", fn->nbody);
curfn = fn; curfn = fn;
if(debug['W']) {
snprint(s, sizeof(s), "\nbefore %S", curfn->nname->sym);
dump(s, fn->nbody);
}
walkstate(fn->nbody); walkstate(fn->nbody);
if(debug['W']) {
snprint(s, sizeof(s), "after %S", curfn->nname->sym);
dump(s, fn->nbody);
}
}
void
addtotop(Node *n)
{
Node *l;
while(addtop != N) {
l = addtop;
addtop = N;
walktype(l, Etop);
n->ninit = list(n->ninit, l);
}
}
void
gettype(Node *n)
{
if(debug['W'])
dump("\nbefore gettype", n);
walktype(n, Erv);
addtotop(n);
if(debug['W']) if(debug['W'])
dump("fn", fn->nbody); dump("after gettype", n);
} }
void void
walkstate(Node *n) walkstate(Node *n)
{ {
Node *l, *more; Node *more;
loop: loop:
if(n == N) if(n == N)
...@@ -69,12 +99,7 @@ loop: ...@@ -69,12 +99,7 @@ loop:
break; break;
} }
while(addtop != N) { addtotop(n);
l = addtop;
addtop = N;
walktype(l, Etop);
n->ninit = list(n->ninit, l);
}
if(more != N) { if(more != N) {
n = more; n = more;
...@@ -227,8 +252,8 @@ loop: ...@@ -227,8 +252,8 @@ loop:
goto nottop; goto nottop;
walkstate(n->ninit); walkstate(n->ninit);
walkbool(n->ntest); walkbool(n->ntest);
walkstate(n->nelse);
walkstate(n->nbody); walkstate(n->nbody);
walkstate(n->nelse);
goto ret; goto ret;
case OPROC: case OPROC:
...@@ -307,6 +332,9 @@ loop: ...@@ -307,6 +332,9 @@ loop:
if(top != Etop) if(top != Etop)
goto nottop; goto nottop;
addtop = list(addtop, n->ninit);
n->ninit = N;
l = n->left; l = n->left;
r = n->right; r = n->right;
walktype(l, Elv); walktype(l, Elv);
...@@ -948,6 +976,7 @@ void ...@@ -948,6 +976,7 @@ void
walkbool(Node *n) walkbool(Node *n)
{ {
walktype(n, Erv); walktype(n, Erv);
addtotop(n);
if(n != N && n->type != T) if(n != N && n->type != T)
if(!eqtype(n->type, types[TBOOL], 0)) if(!eqtype(n->type, types[TBOOL], 0))
yyerror("IF and FOR require a boolean type"); yyerror("IF and FOR require a boolean type");
...@@ -1545,6 +1574,8 @@ loop: ...@@ -1545,6 +1574,8 @@ loop:
w = whatis(l); w = whatis(l);
switch(w) { switch(w) {
default: default:
if(l->type == T)
goto out;
if(!isptr[l->type->etype]) { if(!isptr[l->type->etype]) {
badtype(n->op, l->type, T); badtype(n->op, l->type, T);
l = listnext(&save); l = listnext(&save);
...@@ -1588,6 +1619,7 @@ loop: ...@@ -1588,6 +1619,7 @@ loop:
else else
r = list(r, nod(OCALL, on, l)); r = list(r, nod(OCALL, on, l));
out:
l = listnext(&save); l = listnext(&save);
goto loop; goto loop;
} }
......
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