https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63303
--- Comment #12 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #3) > The problem is that we don't have a POINTER_DIFF_EXPR similar to > POINTER_PLUS_EXPR, which would take two pointers and return an integer, and > the FEs emit pointer difference as cast of both the pointers to signed > integral type > and subtracts the integers. > If > ssize_t foo (char *p, char *q) { return p - q; } > is changed into > ssize_t foo (char *p, char *q) { return (ssize_t) p - (ssize_t) q; } > by the FE, then indeed if you have array starting at 0x7fff0000 and ending > at 0x80010000 and subtract those two pointers, you get undefined behavior. > That is undefined behavior not just for ubsan, but for anything else in the > middle-end. > So, if pointer difference is supposed to behave differently, then > we'd either need to represent pointer difference as > ssize_t foo (char *p, char *q) { return (ssize_t) ((size_t) p - (size_t) q); > } > (but we risk missed optimizations that way I'd say), or we'd need a better > representation of it in the middle-end. Note that apart from missing POINTER_DIFF this isn't a middle-end but a frontend issue.