summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKen Thompson <ken@golang.org>2009-03-10 16:49:34 -0700
committerKen Thompson <ken@golang.org>2009-03-10 16:49:34 -0700
commit7b0b557b34b7285c840f941cfe22c9ed07342314 (patch)
tree876043ce91cb7b4b0477c77c4e1bf11af480c8c3 /src
parentc67af3402de9a22624906b23d878a1b6b72a475c (diff)
downloadgolang-7b0b557b34b7285c840f941cfe22c9ed07342314.tar.gz
bug with interaction of variables
declared in cases and heap allocation R=r OCL=26064 CL=26064
Diffstat (limited to 'src')
-rw-r--r--src/cmd/6g/reg.c4
-rw-r--r--src/cmd/gc/swt.c31
2 files changed, 29 insertions, 6 deletions
diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c
index 5b56138b3..a2c64fa9f 100644
--- a/src/cmd/6g/reg.c
+++ b/src/cmd/6g/reg.c
@@ -787,7 +787,9 @@ mkvar(Reg *r, Adr *a)
s = a->sym;
if(s == S)
goto none;
- if(s->name[0] == '!' || s->name[0] == '.')
+// if(s->name[0] == '!')
+// goto none;
+ if(s->name[0] == '.')
goto none;
et = a->etype;
o = a->offset;
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
index 5f014e9a9..0c5e5eed8 100644
--- a/src/cmd/gc/swt.c
+++ b/src/cmd/gc/swt.c
@@ -189,7 +189,6 @@ casebody(Node *sw)
br = nod(OBREAK, N, N);
loop:
-
if(t == N) {
if(oc == N && os != N)
yyerror("first switch statement must be a case");
@@ -259,12 +258,12 @@ loop:
* rebulid case statements into if .. goto
*/
void
-prepsw(Node *sw, int arg)
+exprswitch(Node *sw, int arg)
{
Iter save;
Node *name, *bool, *cas;
Node *t, *a;
-//dump("prepsw before", sw->nbody->left);
+//dump("exprswitch before", sw->nbody->left);
cas = N;
name = N;
@@ -281,7 +280,7 @@ prepsw(Node *sw, int arg)
loop:
if(t == N) {
sw->nbody->left = rev(cas);
-//dump("prepsw after", sw->nbody->left);
+//dump("exprswitch after", sw->nbody->left);
return;
}
@@ -291,6 +290,16 @@ 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(bool == N) {
bool = nod(OXXX, N, N);
@@ -394,6 +403,18 @@ 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 = nod(OLIST, a, bool); // var,bool
@@ -476,7 +497,7 @@ walkswitch(Node *sw)
/*
* convert the switch into OIF statements
*/
- prepsw(sw, arg);
+ exprswitch(sw, arg);
walkstate(sw->nbody);
//print("normal done\n");
}