Hi,

in true_dependence (alias.c) a varying struct
address is considered to never alias a fixed scalar value. This
rule is triggered also in something like the following:

struct foo { int n; };
extern unsigned long c = 0;

{
  int b;

  b = 2;
  ((struct foo*)(&b + c))->n = 3;
}

This is a bit oversimplifyfied. The real testcase unfortunately fails
only on s390 but there with gcc 2.95, 3.4 and 4.2.

true_dependence asks fixed_scalar_and_varying_struct_p whether these
MEMs may be an alias for each other.

The address of b on the stack (%fp - frame pointer):
(mem/f:DI (plus:DI (reg/f:DI 34 %fp)
        (const_int 160 [0xa0])) [4 b+0 S8 A64])

&b + c
(mem/s:DI (plus:DI (reg:DI 74)
        (plus:DI (reg/f:DI 34 %fp)
            (const_int 160 [0xa0]))) [0 <variable>.n+0 S8 A64])

It can be seen that the first MEM has a 'scalar' flag and the second
an 'in struct' flag.

Although I must admit that this doesn't seem to be very sane code
I was wondering why gcc considers these MEMs to not alias each other although
both have the same base address? What c99 rule would back this behaviour?

According to c99 I would say the memory of b should be safely accessible
using a pointer cast to (struct foo*) because the struct member has the
same type as b:

'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), or
        ...'

Bye,

-Andreas-

Reply via email to