Possible gcc bug in strict type aliasing
Mon Sep 26 12:19:00 GMT 2016
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
>> 18.104.22.168 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
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
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
>> 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.
More information about the Gcc-help