Opened 14 years ago

Last modified 12 years ago

#120 new defect

Some HelenOS code breaks strict aliasing rules

Reported by: Jiri Svoboda Owned by:
Priority: major Milestone:
Component: helenos/unspecified Version: mainline
Keywords: Cc:
Blocker for: Depends on:
See also:

Description

According to GCC man page, -fstrict-aliasing is always active for optimization leves -O2, -O3 and -Os. This means HelenOS is compiled with strict aliasing active. But some code in HelenOS does not observe strict aliasing.

GCC strict aliasing rule requires all code to observe aliasing rules as defined by C99 with only one exception — type punning is allowed through the union type. Specifically type punning is disallowed through pointers.

C99 requires that any variable can only be accessed as one specific type, or as char (via char pointer). Important note is that this applies GLOBALLY, not just within the scope of a function or module.

Code in HelenOS that is suspect of breaking strict aliasing rules:

  • memcpy() (unaligned memcpy should be OK, but the aligned version is not)
  • drawing routines

Code not observing the aliasing rules can break any time. Thus such code must be identified and fixed ASAP. If you have any suspicion about code breaking the aliasing rules, please let me know.

Change History (8)

comment:1 by Jiri Svoboda, 14 years ago

C99 also allows to access a variable through a compatible type. Notably you can access a signed integer type as unsigned integer of the same size and vice versa. But if the sizes differ, access is forbidden, e.g. you cannot access a 4-byte int as a two-element array of 2-byte short ints.

comment:2 by Martin Decky, 14 years ago

GCC with -Wall prints a warning in many cases where the strict aliasing rules are not followed. Note that while switching to GCC 4.4.1, many of such cases were fixed in the kernel, but the uspace applications are not compiled with -Werror, thus many warnings are usually ignored by the authors of the code.

I believe that graphics routines and routines such as memcpy() might sometimes break aliasing rules and expect some specific behavior of the compiler if the performance is important. Certainly, these special assumptions must be limited to absolute minimum and must be clearly documented.

comment:3 by Jiri Svoboda, 14 years ago

I believe the reason why this hasn't bitten us yet is that intra-procedural breaking of strict aliasing rules (i.e. accessing your arguments in an unclean manner) can only lead to error when the function in question gets inlined. GCC does not inline regular (non-inline) functions across modules. memcpy() and friends are usually called from other modules (except for some very special cases) so we were lucky.

Also I have to admit that most of the offending code is probably my doing :-)

comment:4 by Martin Decky, 14 years ago

OK, the pragmatic question is: What should we do about it? Should we just put a bold comment about this to the sources or should we fix this somehow? And how? (Preferably without sacrificing the performance.)

Any suggestions?

comment:5 by Jakub Jermář, 14 years ago

Milestone: 0.4.20.5.0

Retargeting for 0.5.0.

comment:6 by Jakub Jermář, 13 years ago

Milestone: 0.5.00.5.1

comment:7 by Jakub Jermář, 12 years ago

Milestone: 0.5.0

in reply to:  4 comment:8 by Jiří Zárevúcky, 12 years ago

Replying to decky:

OK, the pragmatic question is: What should we do about it? Should we just put a bold comment about this to the sources or should we fix this somehow? And how? (Preferably without sacrificing the performance.)

GCC has the may_alias type attribute. What it does is, essentially, it forces the type to be handled the same way as "char" when it comes to aliasing.

Alternatively, solve it Linux-style with -fno-strict-aliasing.

Last edited 12 years ago by Jiří Zárevúcky (previous) (diff)
Note: See TracTickets for help on using tickets.