aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tcc.h2
-rw-r--r--tccgen.c4
-rw-r--r--tccpp.c8
-rw-r--r--tests/tcctest.c8
4 files changed, 16 insertions, 6 deletions
diff --git a/tcc.h b/tcc.h
index 47c3c5f..8b56516 100644
--- a/tcc.h
+++ b/tcc.h
@@ -1234,7 +1234,7 @@ ST_INLN Sym *define_find(int v);
ST_FUNC void free_defines(Sym *b);
ST_FUNC Sym *label_find(int v);
ST_FUNC Sym *label_push(Sym **ptop, int v, int flags);
-ST_FUNC void label_pop(Sym **ptop, Sym *slast);
+ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep);
ST_FUNC void parse_define(void);
ST_FUNC void preprocess(int is_bof);
ST_FUNC void next_nomacro(void);
diff --git a/tccgen.c b/tccgen.c
index c3185ca..f733598 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5861,7 +5861,7 @@ static void block(int *bsym, int *csym, int is_expr)
}
}
/* pop locally defined labels */
- label_pop(&local_label_stack, llabel);
+ label_pop(&local_label_stack, llabel, is_expr);
/* pop locally defined symbols */
--local_scope;
/* In the is_expr case (a statement expression is finished here),
@@ -6948,7 +6948,7 @@ static void gen_function(Sym *sym)
gsym(rsym);
gfunc_epilog();
cur_text_section->data_offset = ind;
- label_pop(&global_label_stack, NULL);
+ label_pop(&global_label_stack, NULL, 0);
/* reset local stack */
local_scope = 0;
sym_pop(&local_stack, NULL, 0);
diff --git a/tccpp.c b/tccpp.c
index 99d3c0a..9ac98a6 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -1376,7 +1376,7 @@ ST_FUNC Sym *label_push(Sym **ptop, int v, int flags)
/* pop labels until element last is reached. Look if any labels are
undefined. Define symbols if '&&label' was used. */
-ST_FUNC void label_pop(Sym **ptop, Sym *slast)
+ST_FUNC void label_pop(Sym **ptop, Sym *slast, int keep)
{
Sym *s, *s1;
for(s = *ptop; s != slast; s = s1) {
@@ -1395,9 +1395,11 @@ ST_FUNC void label_pop(Sym **ptop, Sym *slast)
}
/* remove label */
table_ident[s->v - TOK_IDENT]->sym_label = s->prev_tok;
- sym_free(s);
+ if (!keep)
+ sym_free(s);
}
- *ptop = slast;
+ if (!keep)
+ *ptop = slast;
}
/* eval an expression for #if/#elif */
diff --git a/tests/tcctest.c b/tests/tcctest.c
index 10203ec..f657c14 100644
--- a/tests/tcctest.c
+++ b/tests/tcctest.c
@@ -2899,6 +2899,11 @@ struct hlist_head {
struct hlist_node *first, *last;
};
+void consume_ulong (unsigned long i)
+{
+ i = 0;
+}
+
void statement_expr_test(void)
{
int a, i;
@@ -2954,6 +2959,9 @@ void statement_expr_test(void)
});
printf ("stmtexpr: %d %d %d\n", t, b, c);
printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last);
+
+ /* Test that we can give out addresses of local labels. */
+ consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; }));
}
void local_label_test(void)