From ccc165107518922af1829afe31a246f775302e44 Mon Sep 17 00:00:00 2001 From: Petr Skocik Date: Sun, 5 Mar 2023 22:31:40 +0100 Subject: [PATCH] Create scopes for switches/whiles/do-whiles The C standard has required this since at least C99. A new scope should also be created for ifs, but that's currently breaking tests2/122_vla_reuse. --- tccgen.c | 9 ++++++- tests/tests2/129_scopes.c | 45 ++++++++++++++++++++++++++++++++++ tests/tests2/129_scopes.expect | 0 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/tests2/129_scopes.c create mode 100644 tests/tests2/129_scopes.expect diff --git a/tccgen.c b/tccgen.c index 53a25bf3..ceff794e 100644 --- a/tccgen.c +++ b/tccgen.c @@ -6832,6 +6832,7 @@ again: tcc_tcov_check_line (tcc_state, 0), tcc_tcov_block_begin (tcc_state); if (t == TOK_IF) { + //new_scope(&o); //?? breaks tests2.122 skip('('); gexpr(); skip(')'); @@ -6846,8 +6847,10 @@ again: } else { gsym(a); } + //prev_scope(&o,0); //?? breaks tests2.122 } else if (t == TOK_WHILE) { + new_scope(&o); d = gind(); skip('('); gexpr(); @@ -6858,7 +6861,7 @@ again: gjmp_addr(d); gsym_addr(b, d); gsym(a); - + prev_scope(&o,0); } else if (t == '{') { new_scope(&o); @@ -6970,6 +6973,7 @@ again: prev_scope(&o, 0); } else if (t == TOK_DO) { + new_scope(&o); a = b = 0; d = gind(); lblock(&a, &b); @@ -6979,6 +6983,7 @@ again: gexpr(); skip(')'); skip(';'); + prev_scope(&o,0); c = gvtst(0, 0); gsym_addr(c, d); gsym(a); @@ -6986,6 +6991,7 @@ again: } else if (t == TOK_SWITCH) { struct switch_t *sw; + new_scope(&o); sw = tcc_mallocz(sizeof *sw); sw->bsym = &a; sw->scope = cur_scope; @@ -7031,6 +7037,7 @@ again: dynarray_reset(&sw->p, &sw->n); cur_switch = sw->prev; tcc_free(sw); + prev_scope(&o,0); } else if (t == TOK_CASE) { struct case_t *cr = tcc_malloc(sizeof(struct case_t)); diff --git a/tests/tests2/129_scopes.c b/tests/tests2/129_scopes.c new file mode 100644 index 00000000..092abb12 --- /dev/null +++ b/tests/tests2/129_scopes.c @@ -0,0 +1,45 @@ +#include +enum{ in = 0}; +#define myassert(X) do{ if(!X) printf("%d: assertion failed\n", __LINE__); }while(0) +int main(){ + #if 0 + { + myassert(!in); + if(sizeof(enum{in=1})) myassert(in); + myassert(!in); //OOPS + } + #endif + { + myassert(!in); + switch(sizeof(enum{in=1})) { default: myassert(in); } + myassert(!in); //OOPS + } + { + myassert(!in); + while(sizeof(enum{in=1})) { myassert(in); break; } + myassert(!in); //OOPS + } + { + myassert(!in); + do{ myassert(!in);}while(0*sizeof(enum{in=1})); + myassert(!in); //OOPS + } + + { + myassert(!in); + for(sizeof(enum{in=1});;){ myassert(in); break; } + myassert(!in); //OK + } + { + myassert(!in); + for(;;sizeof(enum{in=1})){ myassert(in); break; } + myassert(!in); //OK + } + { + myassert(!in); + for(;sizeof(enum{in=1});){ myassert(in); break; } + myassert(!in); //OK + } + +} + diff --git a/tests/tests2/129_scopes.expect b/tests/tests2/129_scopes.expect new file mode 100644 index 00000000..e69de29b