From 9dbaab54d1590b424317745eb8f4ea711c14edf9 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Thu, 4 Sep 2008 12:21:10 -0700 Subject: [PATCH] rewriting bugs R=r OCL=14810 CL=14810 --- src/cmd/gc/const.c | 11 ++++ src/cmd/gc/go.h | 4 +- src/cmd/gc/go.y | 84 ++++++++++++++++-------------- src/cmd/gc/subr.c | 1 - src/cmd/gc/walk.c | 126 +++++++++++++++++++++++++++++---------------- 5 files changed, 141 insertions(+), 85 deletions(-) diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c index f8c6acbc0e3..3d967f57855 100644 --- a/src/cmd/gc/const.c +++ b/src/cmd/gc/const.c @@ -24,7 +24,18 @@ convlit(Node *n, Type *t) n->type = n->left->type; return; } + et = t->etype; + switch(et) { + case TARRAY: + case TFUNC: + case TCHAN: + case TMAP: +// case TPTR32: +// case TPTR64: + return; + } + switch(whatis(n)) { default: goto bad1; diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 9a6b0422405..11d8b56b9c5 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -258,7 +258,7 @@ enum OLIST, OCMP, OPTR, OARRAY, ORETURN, OFOR, OIF, OSWITCH, OI2S, OS2I, OI2I, - OAS, OASOP, OCASE, OXCASE, OSCASE, OFALL, OXFALL, + OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL, OGOTO, OPROC, ONEW, OEMPTY, OSELECT, OLEN, OCAP, OPANIC, OPRINT, OTYPEOF, @@ -661,7 +661,9 @@ void doimport8(Node*, Val*, Node*); * walk.c */ void walk(Node*); +void walkstate(Node*); void walktype(Node*, int); +void walkas(Node*); void walkbool(Node*); Type* walkswitch(Node*, Type*(*)(Node*, Type*)); int casebody(Node*); diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y index a02425c3c20..e2dcb088c61 100644 --- a/src/cmd/gc/go.y +++ b/src/cmd/gc/go.y @@ -42,7 +42,7 @@ %type range_header range_body range_stmt select_stmt %type simple_stmt osimple_stmt semi_stmt %type expr uexpr pexpr expr_list oexpr oexpr_list expr_list_r -%type name name_name onew_name new_name new_name_list_r conexpr +%type name name_name onew_name new_name new_name_list_r %type vardcl_list_r vardcl Avardcl Bvardcl %type interfacedcl_list_r interfacedcl %type structdcl_list_r structdcl @@ -182,7 +182,13 @@ Acommon_dcl: { $$ = rev($3); } -| LCONST '(' constdcl_list_r osemi ')' +| LCONST '(' constdcl osemi ')' + { + iota = 0; + lastconst = N; + $$ = N; + } +| LCONST '(' constdcl ';' constdcl_list_r osemi ')' { iota = 0; lastconst = N; @@ -234,7 +240,7 @@ Bvardcl: $$ = nod(OAS, $$, N); } -| new_name_list_r type '=' oexpr_list +| new_name_list_r type '=' expr_list { $$ = rev($1); dodclvar($$, $2); @@ -250,29 +256,43 @@ Bvardcl: } constdcl: - new_name conexpr + new_name type '=' expr { - walktype($2, Erv); - dodclconst($1, $2); - } -| new_name type conexpr - { - walktype($3, Erv); - convlit($3, $2); - dodclconst($1, $3); - } + Node *c = treecopy($4); + walktype(c, Erv); + convlit(c, $2); + dodclconst($1, c); -conexpr: - { - if(lastconst == N) - yyerror("first constant must evaluate an expression"); - $$ = treecopy(lastconst); + lastconst = $4; iota += 1; } -| '=' expr +| new_name '=' expr { - lastconst = $2; - $$ = treecopy(lastconst); + Node *c = treecopy($3); + walktype(c, Erv); + dodclconst($1, c); + + lastconst = $3; + iota += 1; + } + +constdcl1: + constdcl +| new_name type + { + Node *c = treecopy(lastconst); + walktype(c, Erv); + convlit(c, $2); + dodclconst($1, c); + + iota += 1; + } +| new_name + { + Node *c = treecopy(lastconst); + walktype(c, Erv); + dodclconst($1, c); + iota += 1; } @@ -1041,14 +1061,6 @@ Afntypeh: $$ = functype(N, $3, $5); funcnam($$, nil); } -| LFUNC '(' oarg_type_list ')' '.' '(' oarg_type_list ')' Afnres - /* i dont believe that this form is useful for anything */ - { - if($3 == N || $3->op == OLIST) - yyerror("syntax error in method receiver"); - $$ = functype($3, $7, $9); - funcnam($$, nil); - } Bfntypeh: LFUNC '(' oarg_type_list ')' Bfnres @@ -1056,14 +1068,6 @@ Bfntypeh: $$ = functype(N, $3, $5); funcnam($$, nil); } -| LFUNC '(' oarg_type_list ')' '.' '(' oarg_type_list ')' Bfnres - /* i dont believe that this form is useful for anything */ - { - if($3 == N || $3->op == OLIST) - yyerror("syntax error in method receiver"); - $$ = functype($3, $7, $9); - funcnam($$, nil); - } fntype: fntypeh @@ -1168,8 +1172,8 @@ vardcl_list_r: } constdcl_list_r: - constdcl -| constdcl_list_r ';' constdcl + constdcl1 +| constdcl_list_r ';' constdcl1 typedcl_list_r: typedcl @@ -1415,7 +1419,7 @@ keyexpr_list: { $$ = rev($1); } -| expr_list +| oexpr_list /* * the one compromise of a diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 33628d07a1b..c1bb941fc81 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -591,7 +591,6 @@ opnames[] = [OCALLINTER] = "CALLINTER", [OCASE] = "CASE", [OXCASE] = "XCASE", - [OSCASE] = "SCASE", [OCMP] = "CMP", [OFALL] = "FALL", [OCONV] = "CONV", diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index f1889864c1f..661e64efd26 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -16,13 +16,74 @@ walk(Node *fn) if(debug['W']) dump("fn-before", fn->nbody); curfn = fn; - walktype(fn->nbody, Etop); + walkstate(fn->nbody); if(debug['W']) dump("fn", fn->nbody); } void -walktype1(Node *n, int top) +walkstate(Node *n) +{ + Node *l, *more; + +loop: + if(n == N) + return; + + more = N; + switch(n->op) { + + case OLIST: + walkstate(n->left); + more = n->right; + break; + + default: + yyerror("walkstate: %O not a top level statement", n->op); + + case OASOP: + case OAS: + case OCALLMETH: + case OCALLINTER: + case OCALL: + case OSEND: + case ORECV: + case OPRINT: + case OPANIC: + case OFOR: + case OIF: + case OSWITCH: + case OSELECT: + case OEMPTY: + case OBREAK: + case OCONTINUE: + case OGOTO: + case OLABEL: + case OFALL: + case OXCASE: + case OCASE: + case OXFALL: + case ORETURN: + case OPROC: + walktype(n, Etop); + break; + } + + while(addtop != N) { + l = addtop; + addtop = N; + walktype(l, Etop); + n->ninit = list(n->ninit, l); + } + + if(more != N) { + n = more; + goto loop; + } +} + +void +walktype(Node *n, int top) { Node *r, *l; Type *t; @@ -108,11 +169,11 @@ loop: case OFOR: if(top != Etop) goto nottop; - walktype(n->ninit, Etop); + walkstate(n->ninit); walkbool(n->ntest); - walktype(n->nincr, Etop); - n = n->nbody; - goto loop; + walkstate(n->nincr); + walkstate(n->nbody); + goto ret; case OSWITCH: if(top != Etop) @@ -123,9 +184,9 @@ loop: if(n->ntest == N) n->ntest = booltrue; - walktype(n->ninit, Etop); + walkstate(n->ninit); walktype(n->ntest, Erv); - walktype(n->nbody, Etop); + walkstate(n->nbody); // find common type if(n->ntest->type == T) @@ -149,13 +210,6 @@ loop: walkselect(n); goto ret; - case OSCASE: - if(top != Etop) - goto nottop; -// walktype(n->left, Erv); SPECIAL - n = n->right; - goto loop; - case OEMPTY: if(top != Etop) goto nottop; @@ -164,16 +218,16 @@ loop: case OIF: if(top != Etop) goto nottop; - walktype(n->ninit, Etop); + walkstate(n->ninit); walkbool(n->ntest); - walktype(n->nelse, Etop); - n = n->nbody; - goto loop; + walkstate(n->nelse); + walkstate(n->nbody); + goto ret; case OPROC: if(top != Etop) goto nottop; - walktype(n->left, Etop); + walkstate(n->left); goto ret; case OCALLMETH: @@ -345,8 +399,8 @@ loop: if(top != Etop) goto nottop; walktype(n->left, Erv); - n = n->right; - goto loop; + walkstate(n->right); + goto ret; case OXFALL: if(top != Etop) @@ -480,7 +534,7 @@ loop: if(!isptrto(l->left->type, TMAP)) goto com; *n = *mapop(n, top); - goto loop; + goto ret; case OLSH: case ORSH: @@ -1179,8 +1233,8 @@ walkselect(Node *sel) sel->nbody = rev(res); sel->left = N; - walktype(sel->ninit, Etop); - walktype(sel->nbody, Etop); + walkstate(sel->ninit); + walkstate(sel->nbody); //dump("sel", sel); @@ -1476,7 +1530,7 @@ prcompat(Node *n) loop: if(l == N) { - walktype(r, Etop); + walktype(r, Erv); return r; } @@ -1538,7 +1592,7 @@ nodpanic(int32 lineno) on = syslook("panicl", 0); n = nodintconst(lineno); n = nod(OCALL, on, n); - walktype(n, Etop); + walktype(n, Erv); return n; } @@ -2124,7 +2178,7 @@ chanop(Node *n, int top) argtype(on, t->type); // any-1 argtype(on, t->type); // any-2 r = nod(OCALL, on, r); - walktype(r, top); + walktype(r, Etop); break; send2: @@ -2142,7 +2196,7 @@ chanop(Node *n, int top) argtype(on, t->type); // any-1 argtype(on, t->type); // any-2 r = nod(OCALL, on, r); - walktype(r, top); + walktype(r, Etop); break; } return r; @@ -2318,20 +2372,6 @@ arrayop(Node *n, int top) return r; } -void -walktype(Node *n, int top) -{ - Node *r; - - walktype1(n, top); - while(top == Etop && addtop != N) { - r = addtop; - addtop = N; - walktype1(r, top); - n->ninit = list(n->ninit, r); - } -} - void diagnamed(Type *t) {