Commit 0c4f4587 authored by Ken Thompson's avatar Ken Thompson

bug with interaction of variables

declared in cases and heap allocation

R=r
OCL=26064
CL=26064
parent b2e91a9a
...@@ -787,7 +787,9 @@ mkvar(Reg *r, Adr *a) ...@@ -787,7 +787,9 @@ mkvar(Reg *r, Adr *a)
s = a->sym; s = a->sym;
if(s == S) if(s == S)
goto none; goto none;
if(s->name[0] == '!' || s->name[0] == '.') // if(s->name[0] == '!')
// goto none;
if(s->name[0] == '.')
goto none; goto none;
et = a->etype; et = a->etype;
o = a->offset; o = a->offset;
......
...@@ -189,7 +189,6 @@ casebody(Node *sw) ...@@ -189,7 +189,6 @@ casebody(Node *sw)
br = nod(OBREAK, N, N); br = nod(OBREAK, N, N);
loop: loop:
if(t == N) { if(t == N) {
if(oc == N && os != N) if(oc == N && os != N)
yyerror("first switch statement must be a case"); yyerror("first switch statement must be a case");
...@@ -259,12 +258,12 @@ loop: ...@@ -259,12 +258,12 @@ loop:
* rebulid case statements into if .. goto * rebulid case statements into if .. goto
*/ */
void void
prepsw(Node *sw, int arg) exprswitch(Node *sw, int arg)
{ {
Iter save; Iter save;
Node *name, *bool, *cas; Node *name, *bool, *cas;
Node *t, *a; Node *t, *a;
//dump("prepsw before", sw->nbody->left); //dump("exprswitch before", sw->nbody->left);
cas = N; cas = N;
name = N; name = N;
...@@ -281,7 +280,7 @@ prepsw(Node *sw, int arg) ...@@ -281,7 +280,7 @@ prepsw(Node *sw, int arg)
loop: loop:
if(t == N) { if(t == N) {
sw->nbody->left = rev(cas); sw->nbody->left = rev(cas);
//dump("prepsw after", sw->nbody->left); //dump("exprswitch after", sw->nbody->left);
return; return;
} }
...@@ -291,6 +290,16 @@ loop: ...@@ -291,6 +290,16 @@ loop:
goto loop; goto loop;
} }
// pull out the dcl in case this
// variable is allocated on the heap.
// this should be done better to prevent
// multiple (unused) heap allocations per switch.
if(t->ninit != N && t->ninit->op == ODCL) {
//dump("exprswitch case init", t->ninit);
cas = list(cas, t->ninit);
t->ninit = N;
}
if(t->left->op == OAS) { if(t->left->op == OAS) {
if(bool == N) { if(bool == N) {
bool = nod(OXXX, N, N); bool = nod(OXXX, N, N);
...@@ -394,6 +403,18 @@ loop: ...@@ -394,6 +403,18 @@ loop:
goto loop; goto loop;
} }
// pull out the dcl in case this
// variable is allocated on the heap.
// this should be done better to prevent
// multiple (unused) heap allocations per switch.
// not worth doing now -- make a binary search
// on contents of signature instead.
if(t->ninit != N && t->ninit->op == ODCL) {
//dump("typeswitch case init", t->ninit);
cas = list(cas, t->ninit);
t->ninit = N;
}
a = t->left->left; // var a = t->left->left; // var
a = nod(OLIST, a, bool); // var,bool a = nod(OLIST, a, bool); // var,bool
...@@ -476,7 +497,7 @@ walkswitch(Node *sw) ...@@ -476,7 +497,7 @@ walkswitch(Node *sw)
/* /*
* convert the switch into OIF statements * convert the switch into OIF statements
*/ */
prepsw(sw, arg); exprswitch(sw, arg);
walkstate(sw->nbody); walkstate(sw->nbody);
//print("normal done\n"); //print("normal done\n");
} }
......
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