check_access() is called at each run of simplify_loads(). However, a bad access can belong to a dead branch and thus a bad access warning can be issued for code that is not executed, maybe specifically excluded. So, move check_access() to late_warnings(), where all optimizations have been done. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- linearize.c | 6 ++++++ memops.c | 3 --- validation/bad-check-access0.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 validation/bad-check-access0.c diff --git a/linearize.c b/linearize.c index 9fecb4b57e43..0250c6bb17ef 100644 --- a/linearize.c +++ b/linearize.c @@ -2532,6 +2532,12 @@ static void late_warnings(struct entrypoint *ep) continue; if (insn->tainted) check_tainted_insn(insn); + switch (insn->opcode) { + case OP_LOAD: + // Check for illegal offsets. + check_access(insn); + break; + } } END_FOR_EACH_PTR(insn); } END_FOR_EACH_PTR(bb); } diff --git a/memops.c b/memops.c index d96bd8a9090d..0a1106b0e464 100644 --- a/memops.c +++ b/memops.c @@ -147,9 +147,6 @@ static void simplify_loads(struct basic_block *bb) struct pseudo_list *dominators; unsigned long generation; - /* Check for illegal offsets.. */ - check_access(insn); - if (insn->is_volatile) continue; diff --git a/validation/bad-check-access0.c b/validation/bad-check-access0.c new file mode 100644 index 000000000000..3c4c023f2f89 --- /dev/null +++ b/validation/bad-check-access0.c @@ -0,0 +1,31 @@ +#define SIZE 2 +static int buf[SIZE]; + +static inline int swt(int i) +{ + switch (i) { + case 0 ... (SIZE-1): + return buf[i]; + default: + return 0; + } +} + +static int switch_ok(void) { return swt(1); } +static int switch_ko(void) { return swt(2); } + + +static inline int cbr(int i, int p) +{ + if (p) + return buf[i]; + else + return 0; +} + +static int branch_ok(int x) { return cbr(1, x != x); } +static int branch_ko(int x) { return cbr(2, x != x); } + +/* + * check-name: bad-check-access0 + */ -- 2.29.2