]> Cypherpunks repositories - gostls13.git/commitdiff
fix bug30
authorKen Thompson <ken@golang.org>
Sat, 29 Mar 2008 22:37:38 +0000 (15:37 -0700)
committerKen Thompson <ken@golang.org>
Sat, 29 Mar 2008 22:37:38 +0000 (15:37 -0700)
automatic declaration leaking
from one function to another

SVN=114252

src/c/dcl.c
src/c/go.h
src/c/go.y

index f59399746b230540d467ce4a58e6870e394a48ff..abf6b7ac731e8e1816eda3b802dca93a45349f40 100644 (file)
@@ -309,6 +309,7 @@ funchdr(Node *n)
        if(dclcontext != PEXTERN)
                fatal("funchdr: dclcontext");
        dclcontext = PAUTO;
+       markdcl("func");
 
        funcargs(n->type);
        if(n->type->thistuple > 0) {
@@ -364,6 +365,7 @@ funcbody(Node *n)
        if(dclcontext != PAUTO)
                fatal("funcbody: dclcontext");
        dclcontext = PEXTERN;
+       popdcl("func");
 }
 
 /*
@@ -477,7 +479,7 @@ pushdcl(Sym *s)
 }
 
 void
-popdcl(void)
+popdcl(char *why)
 {
        Sym *d, *s;
 
@@ -491,18 +493,38 @@ popdcl(void)
                if(debug['d'])
                        print("\t%ld pop %S\n", curio.lineno, s);
        }
-       if(d != S)
-               d = d->link;
-       dclstack = d;
+       if(d == S)
+               fatal("popdcl: no mark");
+       if(strcmp(why, d->package) != 0)
+               fatal("popdcl: pushed as %s poped as %s", d->package, why);
+       dclstack = d->link;
 }
 
 void
-markdcl(void)
+poptodcl(void)
+{
+       Sym *d, *s;
+
+       for(d=dclstack; d!=S; d=d->link) {
+               if(d->name == nil)
+                       break;
+               s = pkglookup(d->name, d->package);
+               dcopy(s, d);
+               if(debug['d'])
+                       print("\t%ld pop %S\n", curio.lineno, s);
+       }
+       if(d == S)
+               fatal("poptodcl: no mark");
+}
+
+void
+markdcl(char *why)
 {
        Sym *d;
 
        d = push();
        d->name = nil;          // used as a mark in fifo
+       d->package = why;       // diagnostic for unmatched
 //     if(debug['d'])
 //             print("markdcl\n");
 }
@@ -512,7 +534,7 @@ markdclstack(void)
 {
        Sym *d, *s;
 
-       markdcl();
+       markdcl("fnlit");
 
        // copy the entire pop of the stack
        // all the way back to block0.
@@ -529,6 +551,19 @@ markdclstack(void)
        }
 }
 
+void
+testdclstack(void)
+{
+       Sym *d;
+
+       for(d=dclstack; d!=S; d=d->link) {
+               if(d->name == nil) {
+                       yyerror("mark left on the stack");
+                       continue;
+               }
+       }
+}
+
 void
 addvar(Node *n, Node *t, int ctxt)
 {
index eaada806663a92451c9a220882293e654ea348d1..a0fd35e1aa8e769e55edccff0b2f4e8157aaf114 100644 (file)
@@ -446,9 +446,11 @@ void       funcbody(Node*);
 Node*  dostruct(Node*, int);
 Node** stotype(Node*, Node**, Node*);
 Node*  sortinter(Node*);
-void   markdcl(void);
-void   popdcl(void);
+void   markdcl(char*);
+void   popdcl(char*);
+void   poptodcl(void);
 void   markdclstack(void);
+void   testdclstack(void);
 Sym*   pushdcl(Sym*);
 void   addvar(Node*, Node*, int);
 void   addtyp(Node*, Node*, int);
index 0c8fac798ab3e7782ab098bcbe4e77e6dd5506a4..eb122474f2ea4b3bbd301d3faf50bb27641d6120 100644 (file)
@@ -62,6 +62,7 @@ file:
        {
                if(debug['f'])
                        frame(1);
+               testdclstack();
        }
 
 package:
@@ -286,12 +287,12 @@ complex_stmt:
        LFOR for_stmt
        {
                /* FOR and WHILE are the same keyword */
-               popdcl();
+               popdcl("for/while");
                $$ = $2;
        }
 |      LSWITCH if_stmt
        {
-               popdcl();
+               popdcl("if/switch");
                if(!casebody($2->nbody))
                        yyerror("switch statement must have case labels");
                $$ = $2;
@@ -299,18 +300,18 @@ complex_stmt:
        }
 |      LIF if_stmt
        {
-               popdcl();
+               popdcl("if/switch");
                $$ = $2;
        }
 |      LIF if_stmt LELSE else_stmt
        {
-               popdcl();
+               popdcl("if/switch");
                $$ = $2;
                $$->nelse = $4;
        }
 |      LRANGE range_stmt
        {
-               popdcl();
+               popdcl("range");
                $$ = $2;
        }
 |      LRETURN oexpr_list ';'
@@ -322,14 +323,12 @@ complex_stmt:
                // will be converted to OCASE
                // right will point to next case
                // done in casebody()
-               popdcl();
-               markdcl();
+               poptodcl();
                $$ = nod(OXCASE, $2, N);
        }
 |      LDEFAULT ':'
        {
-               popdcl();
-               markdcl();
+               poptodcl();
                $$ = nod(OXCASE, N, N);
        }
 |      LFALL ';'
@@ -369,13 +368,13 @@ complex_stmt:
 compound_stmt:
        '{'
        {
-               markdcl();
+               markdcl("compound");
        } ostmt_list '}'
        {
                $$ = $3;
                if($$ == N)
                        $$ = nod(OEMPTY, N, N);
-               popdcl();
+               popdcl("compound");
        }
 
 for_header:
@@ -404,7 +403,9 @@ for_body:
        }
 
 for_stmt:
-       { markdcl(); } for_body
+       {
+               markdcl("for/while");
+       } for_body
        {
                $$ = $2;
        }
@@ -433,7 +434,9 @@ if_body:
        }
 
 if_stmt:
-       { markdcl(); } if_body
+       {
+               markdcl("if/switch");
+       } if_body
        {
                $$ = $2;
        }
@@ -461,7 +464,9 @@ range_body:
        }
 
 range_stmt:
-       { markdcl(); } range_body
+       {
+               markdcl("range");
+       } range_body
        {
                $$ = $2;
        }
@@ -883,7 +888,7 @@ fnlitdcl:
 fnliteral:
        fnlitdcl '{' ostmt_list '}'
        {
-               popdcl();
+               popdcl("fnlit");
 
                vargen++;
                snprint(namebuf, sizeof(namebuf), "_f%.3ld", vargen);