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

fix bug30

automatic declaration leaking
from one function to another

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