On Fri, Jun 26, 2015 at 4:01 PM, Francisco Jerez <curroje...@riseup.net> wrote: > Davin McCall <dav...@davmac.org> writes: > >> On 26/06/15 14:31, Eirik Byrkjeflot Anonsen wrote: >>> Erik Faye-Lund <kusmab...@gmail.com> writes: >>> >>>> On Fri, Jun 26, 2015 at 1:23 PM, Davin McCall <dav...@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. >>>> >>>> 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. >>>> >>>> Those other spec-quotes doesn't undo the strict-aliasing definitions; >>>> knowing how things are laid out in memory doesn't mean the compiler >>>> cannot assume two differently typed variables doesn't overlap. >>> So basically, you're saying that e.g.: >>> >>> p->next = a; >>> q = exec_node_get_next_const(p); >>> >>> is equivalent to: >>> >>> exec_node * p1 = p; >>> exec_node ** p2 = (exec_node**)p; >>> p1->next = a; >>> q = p2[0]; >> >> It is, once the patch is applied (or if strict aliasing is disabled). >> >>> And at this point p1 and p2 are different types, so the compiler can >>> freely assume that p1 and p2 are non-overlapping. >> >> p1 and p2 are two separate variables and of course they are >> non-overlapping, but *p1 and **p2 are the same type and so may overlap. >> > Also note that even *p1 and *p2 are allowed to overlap even though they > are of different types because of section 6.5 of C99: > > | 7 An object shall have its stored value accessed only by an lvalue > | expression that has one of the following types: > |[...] > | - 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)[...]
I don't see how this wording legitimates the code above. There's no unions involved, so that part is irrelevant. And "n" isn't an aggregate type, it's a pointer type that happens to point to an aggregate type, no? But even if it were, it needs to include one of the "aforementioned" types among its members, which I cannot see that it does either. Care to explain? _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev