[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

aliasing again



I think I am missing something  practical here.

In 4.7.1,  I noticed the code :
RTEMS_INLINE_ROUTINE void _Heap_Block_remove (
  Heap_Block *the_block
)
{
  Heap_Block *block = the_block;

  Heap_Block *next = block->next;
  Heap_Block *prev = block->prev;
  prev->next = next;
  next->prev = prev;
}

What is the effect of this discussion of alias  in
Heap_Block_remove  ?

I extended the test with gcc-4.1.1 with either
-fstrict-aliasing or  -fno-strict-aliasing with or
without  -O -fschedule-insns.  However, I got the
same result :

struct node {
     struct node *next, *prev;
};


void xtract(struct node *x)
{
    struct node *n, *p;
    n = x->next;
    p = x->prev;
    n->prev = p;
    p->next = n;
}

void nodeRemove(struct node *x)
{
    struct node *n, *p;

    n = x->next;
    p = x->prev;
    p->next = n;
    n->prev = p;
}

00000000 <xtract>:
   0: 81 63 00 04  lwz     r11,4(r3)    # r11= p=x->prev
   4: 81 23 00 00  lwz     r9,0(r3)     # r9 = n=x->next
   8: 91 2b 00 00  stw     r9,0(r11)    # p->next = n
   c: 91 69 00 04  stw     r11,4(r9)    # n->prev = p
  10: 4e 80 00 20  blr

00000014 <nodeRemove>:
  14: 81 63 00 04  lwz     r11,4(r3)    # r11 = p=x->prev
  18: 81 23 00 00  lwz     r9,0(r3)     # r9 = n=x->next
  1c: 91 69 00 04  stw     r11,4(r9)    # n->pre = p
  20: 91 2b 00 00  stw     r9,0(r11)    # p->next =n
  24: 4e 80 00 20  blr


Is it possible that I did not build my gcc-4.1.1 with a
correction option ?

Regards,
Kate

Sergei Organov wrote:

> Till Straumann <strauman at slac.stanford.edu> writes:
> > Sergei Organov wrote:
>
> [...]
>
> >> -fstrict-aliasing should have no effect here, I think, as all the
> >> pointers involved have the same type and are therefore allowed to
> >> alias each other anyway.
> >>
> > *wrong* (for the x-th time) -- strict-aliasing *could* have an effect
> > here.
>
> Well, I still don't think it should have an effect here, even though I
> expressed my reasonings incorrectly indeed.
>
> > For the alias rule it is irrelevant if the two pointers are of the
> > same type. What matters is that the *underlying object* matches the
> > pointer.
>
> Yes, the type of pointer must match the effective type of the underlying
> object.
>
> > In this case, 'p' would *NOT* point to a legal 'struct node',
> > hence 'p' would be an illegal alias
>
> [ Note: aliasing rules don't say anything about validity of an object. They talk
>   about effective type of an object. ]
>
> I don't see an evidence that 'p' can never point to an object of type
> 'struct node'. Probably you meant to say that it could be inferred that
> both 'n' and 'p' in the last 2 lines can't *simultaneously* point to
> objects of type 'struct node', provided '&n->prev == &p->next'. Well,
> I'm afraid even that can't be inferred. Consider the following
> counter-example:
>
> // Repeat original code for convenience
> struct node { struct node *next, *prev; };
> void xtract(struct node *x)
> {
>     struct node *n, *p;
>     n = x->next;
>     p = x->prev;
>     n->prev = p;
>     p->next = n;
> }
>
> // The example:
>
> struct xxxx  { struct node *a; struct node n; }
> union u {
>   struct node n;
>   struct xxxx x;
> };
>
> union u u;
>
> // We get the following layout for 'u':
> //   | u.n.next | u.n.prev   |
> //   | u.x.a    | u.x.n.next | u.x.n.prev |
>
> u.x.a = NULL;
> u.x.n.next = &u.n;
> u.x.n.prev = &u.x.n;
> xtract(&u.x.n)
> // Call expansion:
> //    n = u.x.n.next; => n = &u.n;
> //    p = u.x.n.prev; => p = &u.x.n;
> //    n->prev = p;    => u.n.prev = &u.x.n;
> //    p->next = n;    => u.x.n.next = &u.n;
>
> In this case both 'n' and 'p' will point to 2 different objects of type
> 'struct node' in the last 2 lines of the xtract(), yet 'n->prev' and
> 'p->next' will have the same address. Therefore, aliasing rules are not
> violated here.
>
> Now, one can argue that the code still violates union usage rules in the
> standard, and he will be right. But unlike the standard, GCC explicitly
> allows type punning through unions, and I think here lies the root of
> GCC problem with this code. I believe GCC should not be allowed to
> reorder last 2 lines provided type punning through unions is guaranteed
> to work. Though, due to GCC guaranties about unions aren't specified
> strictly enough, I'd have hard times to argue against an opposite
> opinion, I'm afraid.
>
> Disclaimer: the issues involved are indeed rather vague, so I won't be
> surprised if I still miss something. Anyway, in my opinion such tricks
> should simply be avoided.
>
> -- Sergei.
> _______________________________________________
> rtems-users mailing list
> rtems-users at rtems.com
> http://rtems.rtems.org/mailman/listinfo/rtems-users