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-