[PATCH] Fix for bug 21725: wrong results with union and strict-aliasing

Jeroen Dobbelaere jeroen.dobbelaere at gmail.com
Wed Mar 18 02:22:08 PDT 2015

On Tue, Mar 17, 2015 at 11:55 PM, Daniel Berlin <dberlin at dberlin.org> wrote:

> [..]
> In theory, the last time i remember, you weren't allow to set one member
> of a union and read another.
> But uh, that's not real user code :)
> (and IIRC, it does not say anything real)
This is indeed correct. The main issue is that llvm thinks it is allowed to
reorder 'stores' (as it thinks they are not aliasing),
so that a legal read afterwards will result in a wrong answer (if an
optimization or the backend reorders the stores based on the wrong aliasing

>> If you access a member (or nested member) of a union, starting from the
>> union itself, then it depends if the other type is also accessible through
>> the union.
>> So:
>> int foo(union foo* a, float* b, int* c) {
>>   a->a=1;
>>   *b=2;
>>   // compiler must assume a->a and *b can alias
>>   // compiler must not assume *b and *c alias (access not through union)
>> }
>> (Also see section 3.10 of the c++03 standard;
> This, IMHO, does not say what you seem to think it does :)
> For C++03,  3.10 only includes the word "union" here: "If a program
> attempts to access the stored value of an object through an lvalue of other
> than one of the following types the behavior is undefined:
> — the dynamic type of the object,
> — a cv-qualified version of the dynamic type of the object,
> — a type that is the signed or unsigned type corresponding to the dynamic
> type of the object,
>  — a type that is the signed or unsigned type corresponding to a
> cv-qualified version of the dynamic type of the object,
> — an aggregate or union type that includes one of the aforementioned types
> among its members (including, recursively, a member of a subaggregate or
> contained union),
>  — a type that is a (possibly cv-qualified) base class type of the dynamic
> type of the object,
>  — a char or unsigned char type."
> C++ standard experts, at least on the GCC side, did not view this as
> saying "all accesses must have an explicit union access", but that "It must
> be part of a union type", but about whether you try to access it through a
> union that doesn't have the right actual types in it.
> The type of those objects is right the type of the object. There is, IMHO,
>  nothing illegal about those accesses.
So, with that interpretation, the mere presence of a 'union { short s; int
i; }' (in the same or a different compilation unit) should influence the
(type based) aliasing of all short and int pointers ?
This doesn't look a practical solution to me :(
That's why I settled on the need of having the full access path available
as a practical solution (and one that can easily be explained)..

(btw. Do you have a pointer to the discussion on the gcc side ?)

What we currently have is definitely wrong. Question is how we want to fix


Jeroen Dobbelaere
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150318/a48a035f/attachment.html>

More information about the cfe-commits mailing list