https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93052
Bug ID: 93052 Summary: Wrong optimizations for pointers: `p == q ? p : q` -> `q` Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ch3root at openwall dot com Target Milestone: --- Similar to pr93051. The optimizer sometimes changes `p == q ? p : q` to `q`. This is wrong when the actual provenance of `p` differs from that of `q`. There are two forms -- with the actual conditional operator and with the `if` statement. The ideal example would be constructed with the help of restricted pointers but it's run into a theoretical problem -- see the first testcase in pr92963. My other examples require two conditionals to eliminate the possibility of UB. Comparison of integers should give stable results, hopefully that would be enough to demonstrate the problem. Example with the conditional operator and with dead malloc (the wrong optimization seems to be applied before tree-opt): ---------------------------------------------------------------------- #include <stdint.h> #include <stdlib.h> #include <stdio.h> __attribute__((noipa,optnone)) // imagine it in a separate TU static void *opaque(void *p) { return p; } int main() { int *q = malloc(sizeof(int)); opaque(q); uintptr_t iq = (uintptr_t)(void *)q; free(q); int *p = malloc(sizeof(int)); opaque(p); uintptr_t ip = (uintptr_t)(void *)p; uintptr_t ir = ip == iq ? ip : iq; if (ip == iq) { *p = 1; *(int *)(void *)ir = 2; printf("result: %d\n", *p); } } ---------------------------------------------------------------------- $ gcc -std=c11 -pedantic -Wall -Wextra -Wno-attributes test.c && ./a.out result: 2 $ gcc -std=c11 -pedantic -Wall -Wextra -Wno-attributes -O3 test.c && ./a.out result: 1 ---------------------------------------------------------------------- gcc x86-64 version: gcc (GCC) 10.0.0 20191223 (experimental) ----------------------------------------------------------------------