RFH: aliasing problems

Steven Johnson sjohnson at sakuraindustries.com
Tue Dec 12 05:57:39 UTC 2006


Ralf Corsepius wrote:
> Hi,
>
> I've filed 3 PRs on pretty massive aliasing problems, gcc even diagnoses
> itself:
>
> ftpd.c:
> https://www.rtems.org/bugzilla/show_bug.cgi?id=1184
>
> rtems_glue.c:
> https://www.rtems.org/bugzilla/show_bug.cgi?id=1185
>
> if_ethersubr.c:
> https://www.rtems.org/bugzilla/show_bug.cgi?id=1186
>
> All of them affect all targets and would require careful asm analysis
> and careful fixing.
>   
If you have to resort to ASM analysis to see if you have a problem then 
you have shown the danger and folly of this optimisation. 
> Any help appreciated. I don't think, I'll be able to fix them any time
> soon.
>   
Here is concrete help:

if_ethersubr.c

Line 598, 692
sin = (struct sockaddr_in *)&(ifr->ifr_addr);

change it to
sin = (struct sockaddr_in *)(void*)&(ifr->ifr_addr);

Line 881:
sa = (struct sockaddr *) & ifr->ifr_data;
to
sa = (struct sockaddr *)(void*) & ifr->ifr_data;

Why, because C99 says you can turn any pointer to a void* and any void* 
to any other pointer.  This will silence the warning.  In this case 
there is no possibility for common sub expression elimination as there 
is no manipulation of pointer data between the setting of this value and 
its use that could trigger the optimisation, and it be working from a 
previous state, and not a undetected updated state, and so the warning 
is completely bogus.

rtems_glue.c
change:
        if (rtems_bsdnet_rtrequest (
                RTM_ADD,
                (struct sockaddr *)&address,
                (struct sockaddr *)&gateway,
                (struct sockaddr *)&netmask,
                (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL) < 0) {
to:
        if (rtems_bsdnet_rtrequest (
                RTM_ADD,
                (struct sockaddr *)(void*)&address,
                (struct sockaddr *)(void*)&gateway,
                (struct sockaddr *)(void*)&netmask,
                (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL) < 0) {

No opportunity for common sub expression elimination corrupted by 
intermediary pointer of non-compatible type, so the warning is bogus.  
change silences the warning.

ftpd.c,

line 657

if(bind(s, (struct sockaddr *)&data_source, sizeof(data_source)) >= 0)

change to

if(bind(s, (struct sockaddr *)(void*)&data_source, sizeof(data_source)) 
 >= 0)

Bad Warning, bind is being passed a pointer to data_source, which is a 
local variable to the function which calls bind.  bind can not access 
data_source in any way, except through the pointer it is passed, it has 
no way to modify data_source otherwise.  Therefore bind can never have 
an aliasing issue with regard to its parameter, in this case.  The 
warning makes no sense, and the code here is fully compliant with the 
C99 standard.

line 1448,

uint32_t const *ip   = (uint32_t *)b;      -- This is the line with the 
warning, just chang it to (uint32_t *)(void*)b; to eliminate the warning

      if(*ip == info->def_addr.sin_addr.s_addr)
      {
        info->data_addr.sin_addr.s_addr = *ip;
        info->data_addr.sin_port        = *(uint16_t *)(b + 4); -- but 
if the line above has a warning, then why doesn't this line???  This is 
no better or worse than the above line, yet there is no warning 
generated (nor BTW do i think it should).

In either case, there can be no common sub-expression elimination which 
will cause corruption, because the contents of b are not modified 
between the taking of its pointer and its use.  So the Warning is spurious.

For all the others just change them from (some type*)something to (some 
type*)(void*)something

This will silence the warning. 

The warning for all of these is complete crap.  All of this code is 
legal C99 (that is warned) and none of it can cause the optimiser to 
mis-generate code.

In my opinion the warning is completely useless, getting rid of these 
does not prove there are no more aliasing issues in any of this code.  
The warning SHOULD be generated at the point where common sub-expression 
elimination occurs, AND there is ANY other pointer type dereferenced and 
modified between the point of the early de-reference and where it is 
used.  The warning should state, that the optimisation might generate 
bad code IF any of those de-references modify the optimised variable.  
It should also tell you what variables are possible candidates for 
corrupting the optimisation.  Without this, there is no way to properly 
tell if the code is broken by this optimisation or not.  One thing is 
for certain in my opinion, the code will not be broken without the 
optimisation.

Steven J


> Ralf
>
>
> _______________________________________________
> rtems-users mailing list
> rtems-users at rtems.com
> http://rtems.rtems.org/mailman/listinfo/rtems-users
>
>
>   



More information about the users mailing list