diff options
| author | Michael Matz <matz@suse.de> | 2016-09-04 05:17:08 +0200 |
|---|---|---|
| committer | Michael Matz <matz@suse.de> | 2016-12-15 17:47:11 +0100 |
| commit | 1602998751c8de219514af271a3925b69a6570fb (patch) | |
| tree | 5a1c64d03af9ae1bdbf0f879a9ed40e6fa74cccf | |
| parent | f2a071e808db2896823463089531e08d0b2d0ee8 (diff) | |
| download | tinycc-1602998751c8de219514af271a3925b69a6570fb.tar.gz tinycc-1602998751c8de219514af271a3925b69a6570fb.tar.bz2 | |
Fix more nocode_wanted jump problems
In statement expression we really mustn't emit backward jumps
under nocode_wanted (they will form infinte loops as no expressions
are evaluated). Do-while and explicit loop with gotos weren't
handled.
| -rw-r--r-- | tccgen.c | 14 | ||||
| -rw-r--r-- | tests/tests2/82_nocode_wanted.c | 32 | ||||
| -rw-r--r-- | tests/tests2/82_nocode_wanted.expect | 4 |
3 files changed, 46 insertions, 4 deletions
@@ -5605,8 +5605,9 @@ static void block(int *bsym, int *csym, int is_expr) skip('('); gsym(b); gexpr(); - c = gvtst(0, 0); - gsym_addr(c, d); + c = gvtst(0, 0); + if (!nocode_wanted) + gsym_addr(c, d); skip(')'); gsym(a); skip(';'); @@ -5678,7 +5679,10 @@ static void block(int *bsym, int *csym, int is_expr) gexpr(); if ((vtop->type.t & VT_BTYPE) != VT_PTR) expect("pointer"); - ggoto(); + if (!nocode_wanted) + ggoto(); + else + vtop--; } else if (tok >= TOK_UIDENT) { s = label_find(tok); /* put forward definition if needed */ @@ -5689,7 +5693,9 @@ static void block(int *bsym, int *csym, int is_expr) s->r = LABEL_FORWARD; } vla_sp_restore_root(); - if (s->r & LABEL_FORWARD) + if (nocode_wanted) + ; + else if (s->r & LABEL_FORWARD) s->jnext = gjmp(s->jnext); else gjmp_addr(s->jnext); diff --git a/tests/tests2/82_nocode_wanted.c b/tests/tests2/82_nocode_wanted.c index 18b4914..a0ec890 100644 --- a/tests/tests2/82_nocode_wanted.c +++ b/tests/tests2/82_nocode_wanted.c @@ -27,6 +27,36 @@ static void kb_wait_2(void) timeout--; } while (timeout); } +static void kb_wait_2_1(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + do { + printf("error\n"); + } while (1); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2_2(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + label: + printf("error\n"); + goto label; + }) + ); + timeout--; + } while (timeout); +} static void kb_wait_3(void) { unsigned long timeout = 2; @@ -73,6 +103,8 @@ int main() printf("begin\n"); kb_wait_1(); kb_wait_2(); + kb_wait_2_1(); + kb_wait_2_2(); kb_wait_3(); kb_wait_4(); printf("end\n"); diff --git a/tests/tests2/82_nocode_wanted.expect b/tests/tests2/82_nocode_wanted.expect index 3828ca8..c44d4ea 100644 --- a/tests/tests2/82_nocode_wanted.expect +++ b/tests/tests2/82_nocode_wanted.expect @@ -7,4 +7,8 @@ timeout=2 timeout=1 timeout=2 timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 end |
