commit f5d2d897648174b8bc36fd44e45d24f0e2d44ab0 Author: Moonchild Date: Thu Jan 21 00:29:27 2021 -0800 fix scoping diff --git a/tccgen.c b/tccgen.c index 5f83bdc..99ac830 100644 --- a/tccgen.c +++ b/tccgen.c @@ -7012,7 +7012,7 @@ static void lblock(int *bsym, int *csym) static void block(int is_expr) { int a, b, c, d, e, t; - struct scope o; + struct scope o, o2; Sym *s; if (is_expr) { @@ -7030,33 +7030,47 @@ again: next(); if (t == TOK_IF) { + new_scope(&o); + skip('('); gexpr(); skip(')'); a = gvtst(1, 0); + new_scope(&o2); block(0); + prev_scope(&o2, 0); if (tok == TOK_ELSE) { d = gjmp(0); gsym(a); next(); + new_scope(&o2); block(0); + prev_scope(&o2, 0); gsym(d); /* patch else jmp */ } else { gsym(a); } + prev_scope(&o, 0); + } else if (t == TOK_WHILE) { + new_scope(&o); + d = gind(); skip('('); gexpr(); skip(')'); a = gvtst(1, 0); b = 0; + new_scope(&o2); lblock(&a, &b); + prev_scope(&o2, 0); gjmp_addr(d); gsym_addr(b, d); gsym(a); + prev_scope(&o, 0); + } else if (t == '{') { new_scope(&o); @@ -7073,7 +7087,7 @@ again: } while (tok != '}') { - decl(VT_LOCAL); + decl(VT_LOCAL); if (tok != '}') { if (is_expr) vpop(); @@ -7159,28 +7173,35 @@ again: gsym(e); } skip(')'); + new_scope(&o2); lblock(&a, &b); + prev_scope(&o2, 0); gjmp_addr(d); gsym_addr(b, d); gsym(a); prev_scope(&o, 0); } else if (t == TOK_DO) { + new_scope(&o); a = b = 0; d = gind(); lblock(&a, &b); gsym(b); skip(TOK_WHILE); skip('('); - gexpr(); + new_scope(&o2); + gexpr(); + prev_scope(&o2, 0); skip(')'); skip(';'); - c = gvtst(0, 0); - gsym_addr(c, d); + c = gvtst(0, 0); + gsym_addr(c, d); gsym(a); + prev_scope(&o, 0); } else if (t == TOK_SWITCH) { struct switch_t *sw; + new_scope(&o); sw = tcc_mallocz(sizeof *sw); sw->bsym = &a; @@ -7191,6 +7212,7 @@ again: skip('('); gexpr(); skip(')'); + new_scope(&o2); sw->sv = *vtop--; /* save switch value */ a = 0; @@ -7225,6 +7247,8 @@ again: dynarray_reset(&sw->p, &sw->n); cur_switch = sw->prev; tcc_free(sw); + prev_scope(&o2, 0); + prev_scope(&o, 0); } else if (t == TOK_CASE) { struct case_t *cr = tcc_malloc(sizeof(struct case_t)); diff --git a/tests/tests2/123_statement_scopes.c b/tests/tests2/123_statement_scopes.c new file mode 100644 index 0000000..92e6107 --- /dev/null +++ b/tests/tests2/123_statement_scopes.c @@ -0,0 +1,44 @@ +#include + +int +f1 (int i) +{ + struct foo { int m; }; + if (i > sizeof(struct foo { int m; })) + return sizeof(struct foo { int m; }); + else + return sizeof(struct foo); +} + +int +f2 (void) +{ + struct foo { int m; }; + for (struct foo { int m; } x;;) + return sizeof(struct foo { int m; }); +} + +int +f3 (void) +{ + struct foo { int a; }; + while (sizeof(struct foo { int a; })) + return sizeof(struct foo { int m; }); +} + +int +f4 (int i) +{ + for (struct foo *x = (struct foo { int m; }*)&i;;) + return x->m + sizeof(struct foo { int m; }); +} + +int +main (void) +{ + assert(f1(1) == sizeof(int)); + assert(f2() == sizeof(int)); + assert(f3() == sizeof(int)); + assert(f4(9) == 9 + sizeof(int)); +} + diff --git a/tests/tests2/123_statement_scopes.expect b/tests/tests2/123_statement_scopes.expect new file mode 100644 index 0000000..e69de29