On 26/09/16 12:35, David Brown wrote: > On 26/09/16 11:32, Andrew Haley wrote: >> On 25/09/16 22:46, David Brown wrote: >> >> I think the bug is here: >> >>> temp = *t2p; // Read as T2 >>> t1p2 = (T1*)t2p; // Visible T2 to T1 pointer conversion >>> *t1p2 = temp; // Write as T1 >> >> 6.3.2.3 Pointers >> >> 7 A pointer to an object type may be converted to a pointer to a >> different object type. If the resulting pointer is not correctly >> aligned for the referenced type, the behavior is undefined. >> Otherwise, when converted back again, the result shall compare equal >> to the original pointer. >> >> Note that you have permission only to convert the pointer back to the >> original type and compare it. You don't have permission to >> dereference it as a different type. IMO your program is undefined. >> >> This is key to alias analysis: we know that a pointer to T1 can only >> point to objects compatible with T1. It's not possible to "hide" a >> pointer to T2 from the compiler by converting it to T1, passing it to >> a function, and then converting it back to T2 and dereferencing it. > > But with "*t1p2 = temp;", we are writing as a T1 through a pointer to > T1. Then the return value is also read via a pointer to a T1 ("return > *t1p;"). Sure, but we already have UB at that point, so the program can do anything. Once you have UB, all bets are off. > It looks like gcc is simply ignoring the "*t1p2 = temp;" statement. > This may be because it knows any attempt to dereference t1p2 is > undefined (since it was created from a cast from a different pointer > type), I think so. > If so, it seems like quite an aggressive optimisation, and one that > may surprise people. Probably, but it's the rule which makes type-based alias optimization possible. >> If you lie to the compiler, it will get its revenge. >> > > Yes, I know. (I didn't write the code - it was created as an example of > code that may show questionable code generation in gcc.) > > I'm okay with the compiler getting its revenge - but I would /really/ > like it to tell me about it! I'm sure, but it's not always even possible to detect this kind of thing, at least not without a lot of additional complication in the compiler and some more false positives. Having said all of that, while I'm pretty sure that GCC is within its rights as a C compiler to do what it does, there is no warning and even -fsanitize=undefined does not warn. And it really should, so at the minimum there is some opportunity to improve GCC. Andrew.