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)[...] >> Thus the two >> assignments can be "safely" reordered. Sounds plausible to me. > > The assignments are to 'p1->next' and 'p2[0]', which *are* the same type > (struct exec_node *) and therefore the assignments *cannot* be > reordered. It is exactly this that I rely on in my patch to resolve the > aliasing issue with the current code. > >> And note that casting via void* won't help. "p == (void*)p" compares a >> variable of type "exec_node*" to a variable of type "void*", and thus >> there's no strict-aliasing problem. But "p == (exec_node**)(void*)p" >> compares an "exec_node*" to an "exec_node**" and thus the compiler can >> assume that they are not the same. > > The compiler cannot assume pointers are not the same based on their > type, unless the pointers are de-referenced, which they are not in the > example you just gave. Strictly speaking C99 doesn't even allow the > comparison of 'p == (exec_node**)(void*)p', but all the compilers I know > of allow it, and AFAIK give the same result as if one operand were cast > to the same type as the other. > > Davin > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev
signature.asc
Description: PGP signature
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev