diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-23 16:43:05 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-23 16:43:05 -0700 |
commit | 7e5f1c2eba1426e414698071dd0de7d039eb385d (patch) | |
tree | 3283d90de70f27392955de5a59626309f31fff8a | |
parent | 658ee8e0f63121c5029d91b4d5df169c6ddfcbb8 (diff) | |
download | sparse-7e5f1c2eba1426e414698071dd0de7d039eb385d.tar.gz |
I'm sure there was some reason that was done, but it's trivially broken,
and means that the signedness bits are cleared.
In particular, it means that MOD_UNSIGNED is dropped off a 'bitwise'
type, and this trivial test-case shows the resulting breakage:
typedef unsigned int __attribute__((bitwise)) le32;
static long test(void)
{
return (le32) -1 <= (le32) 0;
}
and without the MOD_UNSIGNED on the bitwise type, this will end up as a
signed compare and return true (1):
[torvalds@ryzen sparse]$ ./test-linearize t.c
test:
.L0:
<entry-point>
ret.64 $1
when it clearly should return false (0).
At the same time this bit masking was very clearly intentional, and goes
all the way back to the original bitwise support in commit 032f492a
("[PATCH] __attribute__((bitwise))"), so there is probably some very
real reason for it despite the above obvious failure.
It's entirely possible that the real issue is that our signedness tests
are very lazy, and just look at
expr->ctype->ctype.modifiers & MOD_UNSIGNED
when it's very possible that they should simply drill deeper into the
type, and we should just use our is_signed_type() helper everywhere,
instead of just looking at the top-level 'modifiers' value.
But we do that 'look at modifiers directly' quite a _lot_.
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/types.rst | 2 | ||||
-rw-r--r-- | parse.c | 1 |
2 files changed, 1 insertions, 2 deletions
diff --git a/Documentation/types.rst b/Documentation/types.rst index 974f9861..dd5bb210 100644 --- a/Documentation/types.rst +++ b/Documentation/types.rst @@ -125,7 +125,7 @@ SYM_RESTRICT Used for bitwise types (aka 'restricted' types): * .ctype.base_type points to the underlying type (integer) * .ctype.modifiers & .as are like for SYM_NODE and the modifiers - are inherited from the base type with MOD_SPECIFIER removed + are inherited from the base type * .ident is the typedef name (if any). SYM_FOULED @@ -1586,7 +1586,6 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta } type = alloc_symbol(token->pos, SYM_BASETYPE); *type = *ctx->ctype.base_type; - type->ctype.modifiers &= ~MOD_SPECIFIER; type->ctype.base_type = ctx->ctype.base_type; type->type = SYM_RESTRICT; ctx->ctype.base_type = type; |