aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2016-09-04 05:21:19 +0200
committerMichael Matz <matz@suse.de>2016-12-15 17:47:11 +0100
commit892c3d996f77c7874d4b2ee9f27812bca1903839 (patch)
tree717383e571b3c769e809680af1d08fd0ae205882
parent1602998751c8de219514af271a3925b69a6570fb (diff)
downloadtinycc-892c3d996f77c7874d4b2ee9f27812bca1903839.tar.gz
tinycc-892c3d996f77c7874d4b2ee9f27812bca1903839.tar.bz2
Reject jumping inside stmtexprs
One can't jump into statement expressions from outside them, like the following: int i = ({ label: foo(); 42; }); goto label; We reject this by making the labels simply not available outside (GCC has a nicer error message about jumping into a statement expression).
-rw-r--r--tccgen.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/tccgen.c b/tccgen.c
index 53ce185..02e56eb 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -5406,7 +5406,7 @@ static void block(int *bsym, int *csym, int is_expr)
gsym(a);
gsym_addr(b, d);
} else if (tok == '{') {
- Sym *llabel;
+ Sym *llabel, *glabel;
int block_vla_sp_loc = vla_sp_loc, saved_vlas_in_scope = vlas_in_scope;
next();
@@ -5414,6 +5414,10 @@ static void block(int *bsym, int *csym, int is_expr)
s = local_stack;
llabel = local_label_stack;
++local_scope;
+ /* Labels defined inside statement expressions aren't
+ available from the outside, so record that as well. */
+ if (is_expr)
+ glabel = global_label_stack;
/* handle local labels declarations */
if (tok == TOK_LABEL) {
@@ -5439,6 +5443,8 @@ static void block(int *bsym, int *csym, int is_expr)
block(bsym, csym, is_expr);
}
}
+ if (is_expr)
+ label_pop(&global_label_stack, glabel);
/* pop locally defined labels */
label_pop(&local_label_stack, llabel);
/* pop locally defined symbols */