we activate code (CODE_ON) only when the target labels are used, which doesn't happen during nocode_wanted regions. So, we cannot just switch off code either during nocode_wanted regions, nothing would switch it on again (except in the happy coincidences when we outright save/restore nocode_wanted). See the testcase for one example, reduced from code generated by yarpgen: in ext = (xxx || 1) // #1 || ((xxx && 1) || 1) // #2 code is first suppressed in #1 normally, then (before this commit) was suppressed via CODE_OFF during #2 (via indirect gjmp), then the suppression from #1 was undone, but nothing undoes the suppression from #2 anymore as everything therein was generated while nocode_wanted was active. So, we would either need to save/restore nocode_wanted around some more expressions, activate CODE_ON also with unused labels (breaks some optimizations we want), or deactivate CODE_OFF only when not already in nocode_wanted state. This does the latter.
Unified · Split
| @@ -56,7 +56,7 @@ ST_DATA int nocode_wanted; /* no code generation wanted */ · 55 unmodified lines | ||
| 56 | 56 | #define unevalmask 0xffff /* unevaluated subexpression */ |
| 57 | 57 | #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */ |
| 58 | 58 | #define DATA_ONLY_WANTED 0x80000000 /* ON outside of functions and for static initializers */ |
| 59 | −#define CODE_OFF() (nocode_wanted |= 0x20000000) | |
| 59 | +#define CODE_OFF() if(!nocode_wanted)(nocode_wanted |= 0x20000000) | |
| 60 | 60 | #define CODE_ON() (nocode_wanted &= ~0x20000000) |
| 61 | 61 | |
| 62 | 62 | ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ |
| @@ -44,6 +44,16 @@ void bla(void) · 43 unmodified lines | ||
| 44 | 44 | get_args(!!__ret, sizeof(__ret)); |
| 45 | 45 | } |
| 46 | 46 | |
| 47 | +int ext; | |
| 48 | + | |
| 49 | +void broken_jumpopt (int xxx) | |
| 50 | +{ | |
| 51 | + /* This was broken in 8227db3a2 by code suppression during suppressed | |
| 52 | + code :) */ | |
| 53 | + ext = (xxx || 1) || ((xxx && 1) || 1); | |
| 54 | + printf("okay: %d %d\n", xxx, ext); | |
| 55 | +} | |
| 56 | + | |
| 47 | 57 | _Bool chk(unsigned long addr, unsigned long limit, unsigned long size) |
| 48 | 58 | { |
| 49 | 59 | _Bool ret; |
| @@ -65,5 +75,6 @@ int main() · 15 unmodified lines | ||
| 65 | 75 | else |
| 66 | 76 | printf("okay\n"); |
| 67 | 77 | bla(); |
| 78 | + broken_jumpopt(42); | |
| 68 | 79 | return 0; |
| 69 | 80 | } |
| @@ -1,2 +1,3 @@ | ||
| 1 | 1 | okay |
| 2 | 2 | okay |
| 3 | +okay: 42 1 | |