[cfe-dev] [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
information).



>> 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
it...

Greetings,

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


More information about the cfe-dev mailing list