You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The C standard Section 6.5 defines the strict aliasing rule as follows.
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
a type compatible with the effective type of the object,
a qualified version of a type compatible with the effective type of the object,
a type that is the signed or unsigned type corresponding to the effective type of the object,
a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
a character type.
In user/sh.c, all pointers to different types of commands are converted to struct cmd*:
At this point, it seems to me that this access (cmd->type) violates the strict aliasing rules, since struct cmd* and struct execcmd* (for example) cannot be aliased:
struct execcmd does not contain any members whose types are compatible with struct cmd.
struct cmd is not a character type.
IMHO, the correct thing to do is to replace int type; with struct cmd type;. By doing so, we can then alias struct cmd* and struct execcmd*. CPython does the same (PEP 3123).
In addition, this gives us more reassurance about pointer conversions (from struct execcmd* to struct cmd*). According to C standard 6.7.2.1, "A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning."
(Although this project is written in ANSI C, the C version is not specified as a compiler flag. Therefore, I assume it should follow the C17 standard as the version of gcc installed on my machine is 12.2.0, which uses -std=gnu17.)
The text was updated successfully, but these errors were encountered:
yuxqiu
changed the title
Violation of the strict aliasing rule in user/sh.c
Does user/sh.c violate the strict aliasing rules?
Aug 23, 2023
The C standard Section 6.5 defines the strict aliasing rule as follows.
In
user/sh.c
, all pointers to different types of commands are converted tostruct cmd*
:xv6-riscv/user/sh.c
Lines 196 to 221 in f5b93ef
The returned pointer is then used to access the
type
field:xv6-riscv/user/sh.c
Lines 71 to 130 in f5b93ef
At this point, it seems to me that this access (
cmd->type
) violates the strict aliasing rules, sincestruct cmd*
andstruct execcmd*
(for example) cannot be aliased:struct cmd
is not compatible withstruct execcmd
.struct cmd
is not a signed/unsigned type.struct execcmd
does not contain any members whose types are compatible withstruct cmd
.struct cmd
is not a character type.IMHO, the correct thing to do is to replace
int type;
withstruct cmd type;
. By doing so, we can then aliasstruct cmd*
andstruct execcmd*
. CPython does the same (PEP 3123).struct execcmd*
tostruct cmd*
). According to C standard 6.7.2.1, "A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning."(Although this project is written in ANSI C, the C version is not specified as a compiler flag. Therefore, I assume it should follow the C17 standard as the version of gcc installed on my machine is 12.2.0, which uses
-std=gnu17
.)The text was updated successfully, but these errors were encountered: