Opened 15 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 , 15 years ago
comment:2 by , 15 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 , 15 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
follow-up: 8 comment:4 by , 15 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:6 by , 14 years ago
Milestone: | 0.5.0 → 0.5.1 |
---|
comment:7 by , 13 years ago
Milestone: | 0.5.0 |
---|
comment:8 by , 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.
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.