char p[1], q[1] = {0};
uintptr_t ip = (uintptr_t)(p+1);
uintptr_t iq = (uintptr_t)q;
if (iq == ip) {
*(p+1) = 10; // <- This line changed
print(q[0]);
}
From the article: "LLVM IR (just like C) does not permit memory accesses through one-past-the-end pointers." I think this is a mental shortcut we make that can lead us astray here. Of course, one-past-the-end pointers can't usually be dereferenced legally. But I think it's legal here because when (iq == ip), (p+1) points to a valid location. I don't see (at least in the C99 standard) why this code would be illegal.
[1] https://www.ralfj.de/blog/2018/07/24/pointers-and-bytes.html
[2] http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_260.htm