may_alias attribute "lost" in internal references, while defining aggregate types

Michal Soltys soltys@ziu.info
Wed Nov 20 10:22:00 GMT 2013


At least that's what I'm suspecting. Consider following example:

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;
         pp = &test.p;

         return 0;
}

The "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.

This can be workarounded with a simple typedef and a cast (not 
necessarily adding to the readabilty though) if one wants to avoid the 
warning, e.g.:

typedef struct tag_s *tag_t_pa __attribute__((may_alias));
tag_t_pa *pp;
pp = (tag_t_pa *)&test.p;

Also - simple forward declaration will have no effect, e.g.

struct __attribute__((may_alias)) tag_s;


To sum up - as far as I can understand:

tag_si is defined earlier - so everything works as expected while being 
used in the definition of tag_s.

tag_s on the other hand - while being referenced inside its own 
definition - "forgets" may_alias and causes incompatible type warning.

Is this expected behaviour ? Shouldn't may_alias be always used 
(including inside-definition references) once after it's been seen for 
the first time on the definition ? Or is there something else I'm 
missing ...



More information about the Gcc-help mailing list