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.
Unified · Split
| @@ -5605,8 +5605,9 @@ static void block(int *bsym, int *csym, int is_expr) · 5604 unmodified lines | ||
| 5605 | 5605 | skip('('); |
| 5606 | 5606 | gsym(b); |
| 5607 | 5607 | gexpr(); |
| 5608 | − c = gvtst(0, 0); | |
| 5609 | − gsym_addr(c, d); | |
| 5608 | + c = gvtst(0, 0); | |
| 5609 | + if (!nocode_wanted) | |
| 5610 | + gsym_addr(c, d); | |
| 5610 | 5611 | skip(')'); |
| 5611 | 5612 | gsym(a); |
| 5612 | 5613 | skip(';'); |
| @@ -5678,7 +5679,10 @@ static void block(int *bsym, int *csym, int is_expr) · 65 unmodified lines | ||
| 5678 | 5679 | gexpr(); |
| 5679 | 5680 | if ((vtop->type.t & VT_BTYPE) != VT_PTR) |
| 5680 | 5681 | expect("pointer"); |
| 5681 | − ggoto(); | |
| 5682 | + if (!nocode_wanted) | |
| 5683 | + ggoto(); | |
| 5684 | + else | |
| 5685 | + vtop--; | |
| 5682 | 5686 | } else if (tok >= TOK_UIDENT) { |
| 5683 | 5687 | s = label_find(tok); |
| 5684 | 5688 | /* put forward definition if needed */ |
| @@ -5689,7 +5693,9 @@ static void block(int *bsym, int *csym, int is_expr) · 4 unmodified lines | ||
| 5689 | 5693 | s->r = LABEL_FORWARD; |
| 5690 | 5694 | } |
| 5691 | 5695 | vla_sp_restore_root(); |
| 5692 | − if (s->r & LABEL_FORWARD) | |
| 5696 | + if (nocode_wanted) | |
| 5697 | + ; | |
| 5698 | + else if (s->r & LABEL_FORWARD) | |
| 5693 | 5699 | s->jnext = gjmp(s->jnext); |
| 5694 | 5700 | else |
| 5695 | 5701 | gjmp_addr(s->jnext); |
| @@ -27,6 +27,36 @@ static void kb_wait_2(void) · 26 unmodified lines | ||
| 27 | 27 | timeout--; |
| 28 | 28 | } while (timeout); |
| 29 | 29 | } |
| 30 | +static void kb_wait_2_1(void) | |
| 31 | +{ | |
| 32 | + unsigned long timeout = 2; | |
| 33 | + do { | |
| 34 | + (1 ? | |
| 35 | + printf("timeout=%ld\n", timeout) : | |
| 36 | + ({ | |
| 37 | + do { | |
| 38 | + printf("error\n"); | |
| 39 | + } while (1); | |
| 40 | + }) | |
| 41 | + ); | |
| 42 | + timeout--; | |
| 43 | + } while (timeout); | |
| 44 | +} | |
| 45 | +static void kb_wait_2_2(void) | |
| 46 | +{ | |
| 47 | + unsigned long timeout = 2; | |
| 48 | + do { | |
| 49 | + (1 ? | |
| 50 | + printf("timeout=%ld\n", timeout) : | |
| 51 | + ({ | |
| 52 | + label: | |
| 53 | + printf("error\n"); | |
| 54 | + goto label; | |
| 55 | + }) | |
| 56 | + ); | |
| 57 | + timeout--; | |
| 58 | + } while (timeout); | |
| 59 | +} | |
| 30 | 60 | static void kb_wait_3(void) |
| 31 | 61 | { |
| 32 | 62 | unsigned long timeout = 2; |
| @@ -73,6 +103,8 @@ int main() · 40 unmodified lines | ||
| 73 | 103 | printf("begin\n"); |
| 74 | 104 | kb_wait_1(); |
| 75 | 105 | kb_wait_2(); |
| 106 | + kb_wait_2_1(); | |
| 107 | + kb_wait_2_2(); | |
| 76 | 108 | kb_wait_3(); |
| 77 | 109 | kb_wait_4(); |
| 78 | 110 | printf("end\n"); |
| @@ -7,4 +7,8 @@ timeout=2 · 6 unmodified lines | ||
| 7 | 7 | timeout=1 |
| 8 | 8 | timeout=2 |
| 9 | 9 | timeout=1 |
| 10 | +timeout=2 | |
| 11 | +timeout=1 | |
| 12 | +timeout=2 | |
| 13 | +timeout=1 | |
| 10 | 14 | end |