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 | skip('('); | 5605 | skip('('); |
| 5606 | gsym(b); | 5606 | gsym(b); |
| 5607 | gexpr(); | 5607 | gexpr(); |
| 5608 | c = gvtst(0, 0); | 5608 | c = gvtst(0, 0); |
| 5609 | gsym_addr(c, d); | 5609 | if (!nocode_wanted) |
| 5610 | gsym_addr(c, d); | ||
| 5610 | skip(')'); | 5611 | skip(')'); |
| 5611 | gsym(a); | 5612 | gsym(a); |
| 5612 | skip(';'); | 5613 | skip(';'); |
| @@ -5678,7 +5679,10 @@ static void block(int *bsym, int *csym, int is_expr) · 65 unmodified lines | |||
| 5678 | gexpr(); | 5679 | gexpr(); |
| 5679 | if ((vtop->type.t & VT_BTYPE) != VT_PTR) | 5680 | if ((vtop->type.t & VT_BTYPE) != VT_PTR) |
| 5680 | expect("pointer"); | 5681 | expect("pointer"); |
| 5681 | ggoto(); | 5682 | if (!nocode_wanted) |
| 5683 | ggoto(); | ||
| 5684 | else | ||
| 5685 | vtop--; | ||
| 5682 | } else if (tok >= TOK_UIDENT) { | 5686 | } else if (tok >= TOK_UIDENT) { |
| 5683 | s = label_find(tok); | 5687 | s = label_find(tok); |
| 5684 | /* put forward definition if needed */ | 5688 | /* put forward definition if needed */ |
| @@ -5689,7 +5693,9 @@ static void block(int *bsym, int *csym, int is_expr) · 4 unmodified lines | |||
| 5689 | s->r = LABEL_FORWARD; | 5693 | s->r = LABEL_FORWARD; |
| 5690 | } | 5694 | } |
| 5691 | vla_sp_restore_root(); | 5695 | vla_sp_restore_root(); |
| 5692 | if (s->r & LABEL_FORWARD) | 5696 | if (nocode_wanted) |
| 5697 | ; | ||
| 5698 | else if (s->r & LABEL_FORWARD) | ||
| 5693 | s->jnext = gjmp(s->jnext); | 5699 | s->jnext = gjmp(s->jnext); |
| 5694 | else | 5700 | else |
| 5695 | gjmp_addr(s->jnext); | 5701 | gjmp_addr(s->jnext); |
| @@ -27,6 +27,36 @@ static void kb_wait_2(void) · 26 unmodified lines | |||
| 27 | timeout--; | 27 | timeout--; |
| 28 | } while (timeout); | 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 | static void kb_wait_3(void) | 60 | static void kb_wait_3(void) |
| 31 | { | 61 | { |
| 32 | unsigned long timeout = 2; | 62 | unsigned long timeout = 2; |
| @@ -73,6 +103,8 @@ int main() · 40 unmodified lines | |||
| 73 | printf("begin\n"); | 103 | printf("begin\n"); |
| 74 | kb_wait_1(); | 104 | kb_wait_1(); |
| 75 | kb_wait_2(); | 105 | kb_wait_2(); |
| 106 | kb_wait_2_1(); | ||
| 107 | kb_wait_2_2(); | ||
| 76 | kb_wait_3(); | 108 | kb_wait_3(); |
| 77 | kb_wait_4(); | 109 | kb_wait_4(); |
| 78 | printf("end\n"); | 110 | printf("end\n"); |
| @@ -7,4 +7,8 @@ timeout=2 · 6 unmodified lines | |||
| 7 | timeout=1 | 7 | timeout=1 |
| 8 | timeout=2 | 8 | timeout=2 |
| 9 | timeout=1 | 9 | timeout=1 |
| 10 | timeout=2 | ||
| 11 | timeout=1 | ||
| 12 | timeout=2 | ||
| 13 | timeout=1 | ||
| 10 | end | 14 | end |