From c771cb52fad4ea07971c2a5f178139991c6fb904 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Tue, 7 Mar 2023 18:10:02 +0100 Subject: [PATCH] Fix code suppression during nocode_wanted 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. --- tccgen.c | 2 +- tests/tests2/88_codeopt.c | 11 +++++++++++ tests/tests2/88_codeopt.expect | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tccgen.c b/tccgen.c index ceff794e..0809760f 100644 --- a/tccgen.c +++ b/tccgen.c @@ -56,7 +56,7 @@ ST_DATA int nocode_wanted; /* no code generation wanted */ #define unevalmask 0xffff /* unevaluated subexpression */ #define NODATA_WANTED (nocode_wanted > 0) /* no static data output wanted either */ #define DATA_ONLY_WANTED 0x80000000 /* ON outside of functions and for static initializers */ -#define CODE_OFF() (nocode_wanted |= 0x20000000) +#define CODE_OFF() if(!nocode_wanted)(nocode_wanted |= 0x20000000) #define CODE_ON() (nocode_wanted &= ~0x20000000) ST_DATA int global_expr; /* true if compound literals must be allocated globally (used during initializers parsing */ diff --git a/tests/tests2/88_codeopt.c b/tests/tests2/88_codeopt.c index 2ab4c8a8..3faa5fac 100644 --- a/tests/tests2/88_codeopt.c +++ b/tests/tests2/88_codeopt.c @@ -44,6 +44,16 @@ void bla(void) get_args(!!__ret, sizeof(__ret)); } +int ext; + +void broken_jumpopt (int xxx) +{ + /* This was broken in 8227db3a2 by code suppression during suppressed + code :) */ + ext = (xxx || 1) || ((xxx && 1) || 1); + printf("okay: %d %d\n", xxx, ext); +} + _Bool chk(unsigned long addr, unsigned long limit, unsigned long size) { _Bool ret; @@ -65,5 +75,6 @@ int main() else printf("okay\n"); bla(); + broken_jumpopt(42); return 0; } diff --git a/tests/tests2/88_codeopt.expect b/tests/tests2/88_codeopt.expect index 439edfd8..76b582b3 100644 --- a/tests/tests2/88_codeopt.expect +++ b/tests/tests2/88_codeopt.expect @@ -1,2 +1,3 @@ okay okay +okay: 42 1