http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59485
Bug ID: 59485
Summary: may_alias attribute ignored in internal references
while defining aggregate types
Product: gcc
Version: 4.8.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: soltys at ziu dot info
Note, I first asked about it on gcc-help, though got no responsens. This does
look like a bug - though obviously I'm not sure if it really should be
considered as such.
Anyway, consider following piece of code:
struct __attribute__((may_alias)) tag_si {
int y;
};
struct __attribute__((may_alias)) tag_s {
int x;
struct tag_si *pi;
struct tag_s *p;
};
int main(void)
{
struct tag_s test = {0};
struct tag_si **ppi;
struct tag_s **pp;
ppi = &test.pi; /* ok */
pp = &test.p; /* will generate warning */
return 0;
}
The possible problem with the above example, is that pp assignment will cause
compiler to emit:
test.c: In function 'main':
test.c:18:12: warning: assignment from incompatible pointer type [enabled by
default]
pp = &test.p;
^
At the same time analogous ppi assignment gives no issues. The only difference
between "tag_si" and "tag_s" is that the former is defined first outside and
then referenced in subsequent definition - while the latter is referenced
during its definition - and then it "forgets" about may_alias attribute (thus
pp = &test.p gives warrning).
I tried to workaround it with preceeding struct forward declaration, e.g.
struct __attribute__((may_alias)) tag_s;
struct __attribute__((may_alias)) tag_s { ......
But this approach has no effect either.
The only workaround for that I found is extra typedef with may_alias and type
cast, e.g.:
typedef struct tag_s *tag_t_pa __attribute__((may_alias));
tag_t_pa *pp;
pp = (tag_t_pa *)&test.p;