diff options
| author | Michael Matz <matz@suse.de> | 2016-09-04 05:21:19 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2016-12-15 17:47:11 +0100 |
| commit | 892c3d996f77c7874d4b2ee9f27812bca1903839 (patch) | |
| tree | 717383e571b3c769e809680af1d08fd0ae205882 | |
| parent | 1602998751c8de219514af271a3925b69a6570fb (diff) | |
| download | tinycc-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.c | 8 |
1 files changed, 7 insertions, 1 deletions
@@ -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 */ |
