aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tccgen.c21
-rw-r--r--tccpp.c12
-rw-r--r--tests/tcctest.c3
3 files changed, 33 insertions, 3 deletions
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;