https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80998
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |ASSIGNED Last reconfirmed| |2017-06-09 Assignee|unassigned at gcc dot gnu.org |jakub at gcc dot gnu.org Ever confirmed|0 |1 --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Created attachment 41524 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41524&action=edit gcc8-pr80998.patch Untested initial implementation. So far it only instruments POINTER_PLUS_EXPR GIMPLE_ASSIGN statements, LLVM seems to instrument also some &a->ptr, a[i], etc., guess we should do the same and more (basically do the rest in spots where ubsan_null is called, just don't call get_base_address on it, but call get_inner_reference instead, and build from that a byte offset to the start. If the base is an automatic var or something like that, ignore it if we can prove it is in-bounds or if -fsanitize=bounds checks the bounds already?, if it is a global var defined in the current TU, similarly. Then what we need and this patch doesn't implement is a sanopt optimization similer to the UBSAN_NULL opts, if we have checked already ptr + i doesn't overflow in a dominating stmt, don't check it again, if we have ptr + 10 and a dominating stmt checked ptr + 15 (i.e. bigger constant), also don't check it. And, there are some inefficiencies in the tests where the offset is variable, while I've tried to use gimple_build in that case, it isn't able to optimize say char *foo (char *p, unsigned int i) { return p + i; } on 64-bit targets by knowing (ssizetype) off >= 0 (where off is i zero extended to sizetype) is always true. Or using value ranges.