[Mesa-dev] [PATCH v2] glsls: Modify exec_list to avoid strict-aliasing violations

Davin McCall davmac at davmac.org
Fri Jun 26 07:16:16 PDT 2015


On 26/06/15 14:53, Erik Faye-Lund wrote:
> On Fri, Jun 26, 2015 at 3:05 PM, Davin McCall <davmac at davmac.org> wrote:
>> On 26/06/15 12:55, Erik Faye-Lund wrote:
>>
>> On Fri, Jun 26, 2015 at 1:23 PM, Davin McCall <davmac at davmac.org> wrote:
>>
>> On 26/06/15 12:03, Davin McCall wrote:
>>
>> ... The stored value of 'n' is not accessed by any other type than the
>> type of n itself. This value is then cast to a different pointer type. You
>> are mistaken if you think that the cast accesses the stored value of n. The
>> other "stored value" access that it occurs in that expression is to the
>> object pointed at by the result of the cast. [...]:
>>
>> I'm sorry, I think that was phrased somewhat abrasively, which I did not
>> intend. Let me try this part again. If we by break up the expression in
>> order of evaluation:
>>
>> From:
>>     return ((const struct exec_node **)n)[0]
>>
>> In order of evaluation:
>>
>> n
>> - which accesses the stored value of n, i.e. a value of type 'struct exec
>> node *', via n, which is obviously of that type.
>>
>> (const struct exec_node **)n
>>   - which casts that value, after it has been retrieved, to another type. If
>> this were an aliasing violation, then casting any pointer variable to
>> another type would be an aliasing violation; this is clearly not the case.
>>
>> ((const struct exec_node **)n)[0]
>> - which de-references the result of the above cast, thereby accessing a
>> stored value of type 'exec node *' using a glvalue of type 'exec node *'.
>>
>> I think breaking this up is a mistake, because the strict-aliasing
>> rules is explicitly about the *combination* of these two things.
>>
>>
>> It is not a mistake, and the strict aliasing rules are not about the
>> combination of these two things.
> It is. In fact, it's not even possible to violate strict-aliasing
> without doing at least two operations. You cannot validate operations
> in a vacuum, because that's not how strict-aliasing is defined.

Any pointer dereference can violate strict aliasing - that's one 
operation. If you mean that it's first necessary to construct a pointer 
value in such a way that de-referencing it will be an aliasing 
violation, then yes, I agree with this statement.

>
>> As I have pointed out, with your reading,
>> pretty much any pointer cast constitutes an aliasing violation.
>>
> No, only those violating the strict aliasing rules I posted before.

... which would only allow changing const/volatile qualifiers, not the 
pointed-to type.

Your reading also disallows casting an 'int' variable to type 'long', 
because that isn't on the list.

>
>> The strict aliasing rules specify what kind of reference you can use to
>> access an object of a particular type. They say nothing about how that
>> reference is obtained.
> Which means that it applies regardless of how you obtain it.

Yes.

> "If a program attempts to access the stored value of an object through
> a glvalue of other than one of the following types the behavior is
> undefined"
>
> It says "if a *program* attempts", not "if a *statement* attempts" or
> "if an *opreation* attempts". This is a whole-program deal, not
> limited to one operation in isolation.

The key part of the wording is "through a glvalue":

"If a program attempts to access the stored value of an object *through
a glvalue* of other than one of the following types ..."

Going back to the original example:

    return ((const struct exec_node **)n)[0]

The glvalue used to access the object in n is n itself. (I do not think 
that '(const struct exec_node **)n' is even a glvalue).


>
>> You *are* accessing the underlying memory of 'n' through a different
>> type, and this is what strict aliasing is all about. But it takes two
>> steps, a single step isn't enough to do so.
>>
>>
>> I'm sorry, but your understanding is incorrect. Most pointer casts would be
>> illegal otherwise. And in fact most casts would be illegal. For instance:
>>
>> int a;
>> long b = (long) a;
>>
>> You reasoning says that the second line is a strict-aliasing violation,
>> because it access the object in 'a' which is of type 'int' via a glvalue of
>> type 'long'.
> No, that is not in violation, because it's accessed through, and *then* casted.


Just as in '((const struct exec_node **)n)[0]', where the value of n is 
accessed through n, and *then* casted.

Davin



More information about the mesa-dev mailing list