diff --git a/tccgen.c b/tccgen.c index 2c759e1..6031611 100644 --- a/tccgen.c +++ b/tccgen.c @@ -4286,6 +4286,25 @@ static int is_label(void) } } +static void label_or_decl(int l) +{ + int last_tok; + + /* fast test first */ + if (tok >= TOK_UIDENT) + { + /* no need to save tokc because tok is an identifier */ + last_tok = tok; + next(); + if (tok == ':') { + unget_tok(last_tok); + return; + } + unget_tok(last_tok); + } + decl(l); +} + static void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg, int is_expr) { @@ -4359,7 +4378,7 @@ static void block(int *bsym, int *csym, int *case_sym, int *def_sym, } } while (tok != '}') { - decl(VT_LOCAL); + label_or_decl(VT_LOCAL); if (tok != '}') { if (is_expr) vpop(); diff --git a/tccpp.c b/tccpp.c index 913bded..f3dd232 100644 --- a/tccpp.c +++ b/tccpp.c @@ -2995,8 +2995,16 @@ ST_INLN void unget_tok(int last_tok) { int i, n; int *q; - unget_saved_macro_ptr = macro_ptr; - unget_buffer_enabled = 1; + if (unget_buffer_enabled) + { + /* assert(macro_ptr == unget_saved_buffer + 1); + assert(*macro_ptr == 0); */ + } + else + { + unget_saved_macro_ptr = macro_ptr; + unget_buffer_enabled = 1; + } q = unget_saved_buffer; macro_ptr = q; *q++ = tok; diff --git a/tests/tcctest.c b/tests/tcctest.c index 03be501..eee7039 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -432,6 +432,7 @@ void loop_test() printf("\n"); } +typedef int typedef_and_label; void goto_test() { @@ -440,6 +441,8 @@ void goto_test() printf("goto:\n"); i = 0; + /* This needs to parse as label, not as start of decl. */ + typedef_and_label: s_loop: if (i >= 10) goto s_end;