Commit dbe004ef authored by Russ Cox's avatar Russ Cox

delayed evaluation of var blocks

R=ken
OCL=32750
CL=32753
parent b8732215
...@@ -1200,6 +1200,7 @@ oldname(Sym *s) ...@@ -1200,6 +1200,7 @@ oldname(Sym *s)
// inner func is referring to var // inner func is referring to var
// in outer func. // in outer func.
if(n->closure == N || n->closure->funcdepth != funcdepth) { if(n->closure == N || n->closure->funcdepth != funcdepth) {
typecheck(&n, Erv);
// create new closure var. // create new closure var.
c = nod(ONAME, N, N); c = nod(ONAME, N, N);
c->sym = s; c->sym = s;
...@@ -1640,21 +1641,15 @@ embedded(Sym *s) ...@@ -1640,21 +1641,15 @@ embedded(Sym *s)
* new_name_list (type | [type] = expr_list) * new_name_list (type | [type] = expr_list)
*/ */
NodeList* NodeList*
variter(NodeList *vl, Node *nt, NodeList *el) variter(NodeList *vl, Node *t, NodeList *el)
{ {
int doexpr, lno; int doexpr, gen;
Node *v, *e, *a; Node *v, *e;
Type *tv; NodeList *init;
NodeList *r; Sym *s;
Type *t; Dcl *r, *d;
t = T;
if(nt) {
typecheck(&nt, Etype);
t = nt->type;
}
r = nil; init = nil;
doexpr = el != nil; doexpr = el != nil;
for(; vl; vl=vl->next) { for(; vl; vl=vl->next) {
if(doexpr) { if(doexpr) {
...@@ -1663,41 +1658,53 @@ variter(NodeList *vl, Node *nt, NodeList *el) ...@@ -1663,41 +1658,53 @@ variter(NodeList *vl, Node *nt, NodeList *el)
break; break;
} }
e = el->n; e = el->n;
el = el->next;
} else } else
e = N; e = N;
v = vl->n; v = vl->n;
tv = t; s = v->sym;
if(e) { if(dclcontext == PEXTERN || dclcontext == PFUNC) {
lno = lineno; r = externdcl;
lineno = v->lineno; gen = 0;
typecheck(&e, Erv); } else {
defaultlit(&e, t); r = autodcl;
if(t) gen = ++vargen;
e = typecheckconv(nil, e, t, 0); pushdcl(s);
if(tv == nil)
tv = e->type;
if(tv && tv->etype == TNIL) {
yyerror("cannot initialize %#N to untyped nil", v);
tv = nil;
}
lineno = lno;
} }
a = N; redeclare("variable", s);
if((e != N && tv != T) || funcdepth > 0) s->def = v;
a = nod(OAS, v, e); // TODO: vargen
dodclvar(v, tv, &r); s->offset = 0;
if(a != N) s->block = block;
r = list(r, a);
if(el) { v->op = ONAME;
el->n = e; v->class = dclcontext;
el = el->next; v->ntype = t;
v->funcdepth = funcdepth;
v->vargen = gen;
if(e != N || funcdepth > 0) {
if(funcdepth > 0)
init = list(init, nod(ODCL, v, N));
e = nod(OAS, v, e);
init = list(init, e);
if(e->right != N)
v->defn = e;
} }
d = dcl();
d->dsym = s;
d->dnode = v;
d->op = ONAME;
r->back->forw = d;
r->back = d;
autoexport(s);
} }
if(el != nil) if(el != nil)
yyerror("extra expr in var dcl"); yyerror("extra expr in var dcl");
return r; return init;
} }
/* /*
...@@ -1830,3 +1837,15 @@ yes: ...@@ -1830,3 +1837,15 @@ yes:
n->type = types[TINT]; n->type = types[TINT];
return n; return n;
} }
void
dclchecks(void)
{
Dcl *d;
for(d=externdcl; d!=D; d=d->forw) {
if(d->op != ONAME)
continue;
typecheck(&d->dnode, Erv);
}
}
...@@ -101,6 +101,7 @@ dumpexportconst(Sym *s) ...@@ -101,6 +101,7 @@ dumpexportconst(Sym *s)
Type *t; Type *t;
n = s->def; n = s->def;
typecheck(&n, Erv);
if(n == N || n->op != OLITERAL) if(n == N || n->op != OLITERAL)
fatal("dumpexportconst: oconst nil: %S", s); fatal("dumpexportconst: oconst nil: %S", s);
...@@ -142,6 +143,7 @@ dumpexportvar(Sym *s) ...@@ -142,6 +143,7 @@ dumpexportvar(Sym *s)
Type *t; Type *t;
n = s->def; n = s->def;
typecheck(&n, Erv);
if(n == N || n->type == T) { if(n == N || n->type == T) {
yyerror("variable exported but not defined: %S", s); yyerror("variable exported but not defined: %S", s);
return; return;
......
...@@ -39,6 +39,7 @@ allocparams(void) ...@@ -39,6 +39,7 @@ allocparams(void)
if(n->class != PAUTO) if(n->class != PAUTO)
continue; continue;
typecheck(&n, Erv);
dowidth(n->type); dowidth(n->type);
w = n->type->width; w = n->type->width;
if(n->class & PHEAP) if(n->class & PHEAP)
......
...@@ -933,6 +933,7 @@ NodeList* constiter(NodeList*, Node*, NodeList*); ...@@ -933,6 +933,7 @@ NodeList* constiter(NodeList*, Node*, NodeList*);
Node* funclit0(Node*); Node* funclit0(Node*);
Node* funclit1(Node*, NodeList*); Node* funclit1(Node*, NodeList*);
Node* unsafenmagic(Node*, NodeList*); Node* unsafenmagic(Node*, NodeList*);
void dclchecks(void);
/* /*
* sinit.c * sinit.c
......
...@@ -123,10 +123,12 @@ file: ...@@ -123,10 +123,12 @@ file:
{ {
if(debug['f']) if(debug['f'])
frame(1); frame(1);
typechecklist($4, Etop);
if(nerrors == 0) if(nerrors == 0)
fninit($4); fninit($4);
if(nsyntaxerrors == 0) if(nsyntaxerrors == 0)
testdclstack(); testdclstack();
dclchecks();
} }
package: package:
...@@ -290,13 +292,11 @@ common_dcl: ...@@ -290,13 +292,11 @@ common_dcl:
$$ = $2; $$ = $2;
if(yylast == LSEMIBRACE) if(yylast == LSEMIBRACE)
yyoptsemi(0); yyoptsemi(0);
// walkdeflist($2);
} }
| LVAR '(' vardcl_list osemi ')' | LVAR '(' vardcl_list osemi ')'
{ {
$$ = $3; $$ = $3;
yyoptsemi(0); yyoptsemi(0);
// walkdeflist($3);
} }
| LVAR '(' ')' | LVAR '(' ')'
{ {
......
...@@ -176,6 +176,35 @@ walkdef(Node *n) ...@@ -176,6 +176,35 @@ walkdef(Node *n)
n->val = e->val; n->val = e->val;
n->type = e->type; n->type = e->type;
break; break;
case ONAME:
if(n->ntype != N) {
typecheck(&n->ntype, Etype);
n->type = n->ntype->type;
if(n->type == T) {
n->diag = 1;
goto ret;
}
n->ntype = N;
}
if(n->type != T)
break;
if(n->defn == N)
fatal("var without type, init: %S", n->sym);
switch(n->defn->op) {
default:
fatal("walkdef name defn");
case OAS:
typecheck(&n->defn->right, Erv);
defaultlit(&n->defn->right, T);
if((t = n->defn->right->type) == T) {
n->diag = 1;
goto ret;
}
n->type = t;
break;
}
break;
} }
ret: ret:
...@@ -1754,11 +1783,8 @@ checkmixed(NodeList *nl, NodeList **init) ...@@ -1754,11 +1783,8 @@ checkmixed(NodeList *nl, NodeList **init)
if(!colasname(l)) if(!colasname(l))
goto allnew; goto allnew;
if(l->sym->block == block) { if(l->sym->block == block)
if(!eqtype(l->type, t))
goto allnew;
nred++; nred++;
}
ntot++; ntot++;
} }
......
...@@ -21,12 +21,12 @@ func main() { ...@@ -21,12 +21,12 @@ func main() {
{ {
// change of type for f // change of type for f
i, f, s := f3(); // GCCGO_ERROR "previous" i, f, s := f3(); // GCCGO_ERROR "previous"
f, g, t := f3(); // ERROR "redeclared|redefinition" f, g, t := f3(); // ERROR "redeclared|redefinition|cannot assign"
} }
{ {
// change of type for i // change of type for i
i, f, s := f3(); // GCCGO_ERROR "previous" i, f, s := f3(); // GCCGO_ERROR "previous"
j, i, t := f3(); // ERROR "redeclared|redefinition" j, i, t := f3(); // ERROR "redeclared|redefinition|cannot assign"
} }
{ {
// no new variables // no new variables
......
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