* [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
@ 2004-11-21 22:55 Jesper Juhl
2004-11-22 1:02 ` Matthew Wilcox
0 siblings, 1 reply; 9+ messages in thread
From: Jesper Juhl @ 2004-11-21 22:55 UTC (permalink / raw)
To: Matthew Wilcox; +Cc: linux-fsdevel, linux-kernel
Hi,
This patch removes a pointless comparison. "arg" is an unsigned long, thus
it can never be <0, so testing that is pointless.
Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>
diff -up linux-2.6.10-rc2-bk6-orig/fs/fcntl.c linux-2.6.10-rc2-bk6/fs/fcntl.c
--- linux-2.6.10-rc2-bk6-orig/fs/fcntl.c 2004-11-17 01:20:14.000000000 +0100
+++ linux-2.6.10-rc2-bk6/fs/fcntl.c 2004-11-21 23:49:20.000000000 +0100
@@ -340,7 +340,7 @@ static long do_fcntl(int fd, unsigned in
break;
case F_SETSIG:
/* arg == 0 restores default behaviour. */
- if (arg < 0 || arg > _NSIG) {
+ if (arg > _NSIG) {
break;
}
err = 0;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
2004-11-21 22:55 [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c Jesper Juhl
@ 2004-11-22 1:02 ` Matthew Wilcox
2004-11-23 9:42 ` Jesper Juhl
0 siblings, 1 reply; 9+ messages in thread
From: Matthew Wilcox @ 2004-11-22 1:02 UTC (permalink / raw)
To: Jesper Juhl; +Cc: Matthew Wilcox, linux-fsdevel, linux-kernel
On Sun, Nov 21, 2004 at 11:55:23PM +0100, Jesper Juhl wrote:
> This patch removes a pointless comparison. "arg" is an unsigned long, thus
> it can never be <0, so testing that is pointless.
>
> Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>
>
> case F_SETSIG:
> /* arg == 0 restores default behaviour. */
> - if (arg < 0 || arg > _NSIG) {
> + if (arg > _NSIG) {
> break;
I've seen patches like this before. I'm generally in favour of removing
the unnecessary test, but Linus rejected it on the grounds the compiler
shouldn't be warning about it and it's better to be more explicit about
the range test. Maybe he's changed his mind between then and now ;-)
--
"Next the statesmen will invent cheap lies, putting the blame upon
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince
himself that the war is just, and will thank God for the better sleep
he enjoys after this process of grotesque self-deception." -- Mark Twain
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
2004-11-22 1:02 ` Matthew Wilcox
@ 2004-11-23 9:42 ` Jesper Juhl
2004-11-23 10:42 ` Jamie Lokier
2004-11-23 18:03 ` Linus Torvalds
0 siblings, 2 replies; 9+ messages in thread
From: Jesper Juhl @ 2004-11-23 9:42 UTC (permalink / raw)
To: Matthew Wilcox, Linus Torvalds; +Cc: linux-fsdevel, linux-kernel
Matthew Wilcox wrote:
> On Sun, Nov 21, 2004 at 11:55:23PM +0100, Jesper Juhl wrote:
>
>>This patch removes a pointless comparison. "arg" is an unsigned long, thus
>>it can never be <0, so testing that is pointless.
>>
>>Signed-off-by: Jesper Juhl <juhl-lkml@dif.dk>
>>
>> case F_SETSIG:
>> /* arg == 0 restores default behaviour. */
>>- if (arg < 0 || arg > _NSIG) {
>>+ if (arg > _NSIG) {
>> break;
>
>
> I've seen patches like this before. I'm generally in favour of removing
> the unnecessary test, but Linus rejected it on the grounds the compiler
> shouldn't be warning about it and it's better to be more explicit about
> the range test. Maybe he's changed his mind between then and now ;-)
>
Let's find out.
Linus, would you accept patches like this?
I've been building recent kernels with -W and there are tons of places
with similar comparisons like the one above, as well as places where
signed and unsigned values are compared, places where values are
potentially truncated in signed/unsigned assignments and similar.
At the very least a review of these code locations to make sure they are
all safe would make sense, and I think it would also make sense to get
rid of the comparisons that always evaluate true or false due to the
signedness or range of datatypes.
I probably won't be able to properly evaluate/review *all* the instances
of this in the kernel, but I don't mind spending some time reviewing
what I can and submit patches, but I don't want to waste my time with it
if you already know up-front that you'll just be dropping all such
patches. Or is this up to the individual maintainers to accept/reject?
If so, then I'll go ahead and submit patches, then the individual
maintainers can ack/nack as they please.
Comments?
--
Jesper Juhl
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
2004-11-23 9:42 ` Jesper Juhl
@ 2004-11-23 10:42 ` Jamie Lokier
2004-11-23 18:28 ` Bryan Henderson
2004-11-23 18:03 ` Linus Torvalds
1 sibling, 1 reply; 9+ messages in thread
From: Jamie Lokier @ 2004-11-23 10:42 UTC (permalink / raw)
To: Jesper Juhl; +Cc: Matthew Wilcox, Linus Torvalds, linux-fsdevel, linux-kernel
Jesper Juhl wrote:
> >> case F_SETSIG:
> >> /* arg == 0 restores default behaviour. */
> >>- if (arg < 0 || arg > _NSIG) {
> >>+ if (arg > _NSIG) {
> >> break;
> >
> Let's find out.
The unusual thing about this function is that "arg" is really
polymorphic, but given type "unsigned long" in the kernel. It is
really a way to hold arbitrary values of any type.
Just look at the way it becomes "unsigned int" (dupfd) or "struct
flock" (lock) or "long" (leases) or "int" (setown).
F_SETOWN is interesting because you really can pass a negative int
argument and get a meaningful result, even though it's passed around
as unsigned long for a little while.
Signal numbers are usually "int". The intended behaviour of fcntl(fd,
F_SETSIG, sig) from userspace is that a negative sig returns EINVAL.
I.e. writing fcntl(fd, F_SETSIG, -1) in userspace will compile without
any warnings. The intended behaviour is that a negative sig returns
EINVAL. The kernel code illustrates that intention.
It isn't obvious that arg is unsigned long in this function, when
reading the code. I had to scroll to the top of the function to check
that this patch doesn't change its behaviour. For that reason I think
the "< 0" test is useful, as it illustrates the intended behaviour and
causes no harm.
-- Jamie
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
2004-11-23 9:42 ` Jesper Juhl
2004-11-23 10:42 ` Jamie Lokier
@ 2004-11-23 18:03 ` Linus Torvalds
2004-11-23 18:39 ` Jesper Juhl
1 sibling, 1 reply; 9+ messages in thread
From: Linus Torvalds @ 2004-11-23 18:03 UTC (permalink / raw)
To: Jesper Juhl; +Cc: Matthew Wilcox, linux-fsdevel, linux-kernel
On Tue, 23 Nov 2004, Jesper Juhl wrote:
>
> Linus, would you accept patches like this?
No, please don't.
The warning is sometimes useful, but when it comes to a construct like
if (a < 0 || a > X)
the fact that "a" is unsigned does not make the construct silly. First
off, it's (a) very readable and (b) the type of "a" may not be immediately
obvious if it's a user typedef, for example.
In fact, the type of "a" might depend on the architecture, or even
compiler flags. Think about "char" - which may or may not be signed
depending on ABI and things like -funsigned-char.
In other places, it's not "unsigned" that is the problem, but the fact
that the range of a type is smaller on one architecture than another. So
you might have
inf fn(pid_t a)
{
if (a > 0xffff)
...
}
which might warn on an architecture where "pid_t" is just sixteen bits
wide. Does that make the code wrong? Hell no.
IOW, a lot of the gcc warnings are just not valid, and trying to shut gcc
up about them can break (and _has_ broken) code that was correct before.
> I probably won't be able to properly evaluate/review *all* the instances
> of this in the kernel,
It's not even that I will drop the patches, it's literally that "fixing"
the code so that gcc doesn't complain can be a BUG. We've gone through
that.
Linus
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
2004-11-23 10:42 ` Jamie Lokier
@ 2004-11-23 18:28 ` Bryan Henderson
0 siblings, 0 replies; 9+ messages in thread
From: Bryan Henderson @ 2004-11-23 18:28 UTC (permalink / raw)
To: Jamie Lokier
Cc: Jesper Juhl, linux-fsdevel, linux-fsdevel-owner, linux-kernel,
Matthew Wilcox, Linus Torvalds
>The unusual thing about this function is that "arg" is really
>polymorphic, but given type "unsigned long" in the kernel. It is
>really a way to hold arbitrary values of any type.
As you've described it, what's wrong with this code is not that it tests
arg < 0, but that it should cast arg to int before doing so:
int signal_arg = (int) arg;
if (signal_arg < 0) ...
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
2004-11-23 18:39 ` Jesper Juhl
@ 2004-11-23 18:37 ` Linus Torvalds
2004-11-23 19:20 ` linux-os
0 siblings, 1 reply; 9+ messages in thread
From: Linus Torvalds @ 2004-11-23 18:37 UTC (permalink / raw)
To: Jesper Juhl; +Cc: Matthew Wilcox, linux-fsdevel, linux-kernel
On Tue, 23 Nov 2004, Jesper Juhl wrote:
>
> Shutting up gcc is not the primary goal here, the goal is/was to
> a) review the code and make sure that it is safe and correct, and fix it
> when it is not.
> b) remove comparisons that are just a waste of CPU cycles when the result
> is always true or false (in *all* cases on *all* archs).
Well, I'm convinced that (b) is unnecessary, as any compiler that notices
the range thing enough to warn will also be smart enough to just remove
the test internally.
But yes, as long as the thing is a "review and fix bugs" and not a quest
to remove warnings which may well be compiler figments, that's obviously
ok.
Linus
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
2004-11-23 18:03 ` Linus Torvalds
@ 2004-11-23 18:39 ` Jesper Juhl
2004-11-23 18:37 ` Linus Torvalds
0 siblings, 1 reply; 9+ messages in thread
From: Jesper Juhl @ 2004-11-23 18:39 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Matthew Wilcox, linux-fsdevel, linux-kernel
On Tue, 23 Nov 2004, Linus Torvalds wrote:
>
>
> On Tue, 23 Nov 2004, Jesper Juhl wrote:
> >
> > Linus, would you accept patches like this?
>
> No, please don't.
>
> The warning is sometimes useful, but when it comes to a construct like
>
> if (a < 0 || a > X)
>
> the fact that "a" is unsigned does not make the construct silly. First
> off, it's (a) very readable and (b) the type of "a" may not be immediately
> obvious if it's a user typedef, for example.
>
> In fact, the type of "a" might depend on the architecture, or even
> compiler flags. Think about "char" - which may or may not be signed
> depending on ABI and things like -funsigned-char.
>
> In other places, it's not "unsigned" that is the problem, but the fact
> that the range of a type is smaller on one architecture than another. So
> you might have
>
> inf fn(pid_t a)
> {
> if (a > 0xffff)
> ...
> }
>
> which might warn on an architecture where "pid_t" is just sixteen bits
> wide. Does that make the code wrong? Hell no.
>
I'm aware that there are pitfalls, one of the very first things I looked
at was the usage of FIRST_USER_PGD_NR in mm/mmap.c:1513 On my main
platform (i386) FIRST_USER_PGD_NR is zero which causes gcc -W to warn
about if (start_index < FIRST_USER_PGD_NR) but, after seeing that it
is not 0 on all platforms I left that one alone.
> IOW, a lot of the gcc warnings are just not valid, and trying to shut gcc
> up about them can break (and _has_ broken) code that was correct before.
>
Shutting up gcc is not the primary goal here, the goal is/was to
a) review the code and make sure that it is safe and correct, and fix it
when it is not.
b) remove comparisons that are just a waste of CPU cycles when the result
is always true or false (in *all* cases on *all* archs).
> > I probably won't be able to properly evaluate/review *all* the instances
> > of this in the kernel,
>
> It's not even that I will drop the patches, it's literally that "fixing"
> the code so that gcc doesn't complain can be a BUG. We've gone through
> that.
>
I'll keep that firmly in mind and only submit patches for these kind of
things if I find usage that is actually (provably) buggy or where it's
completely clear that a comparison will *always* be true or false on all
architectures and removing it does not decrease readability.
I hope that's a more resonable aproach.
Whether or not the list of potential patches is now down to zero remains
to be seen, but it just got a hell of a lot shorter. :)
Thank you for the feedback.
--
Jesper Juhl
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c
2004-11-23 18:37 ` Linus Torvalds
@ 2004-11-23 19:20 ` linux-os
0 siblings, 0 replies; 9+ messages in thread
From: linux-os @ 2004-11-23 19:20 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Jesper Juhl, Matthew Wilcox, linux-fsdevel, linux-kernel
On Tue, 23 Nov 2004, Linus Torvalds wrote:
>
>
> On Tue, 23 Nov 2004, Jesper Juhl wrote:
>>
>> Shutting up gcc is not the primary goal here, the goal is/was to
>> a) review the code and make sure that it is safe and correct, and fix it
>> when it is not.
>> b) remove comparisons that are just a waste of CPU cycles when the result
>> is always true or false (in *all* cases on *all* archs).
>
> Well, I'm convinced that (b) is unnecessary, as any compiler that notices
> the range thing enough to warn will also be smart enough to just remove
> the test internally.
>
> But yes, as long as the thing is a "review and fix bugs" and not a quest
> to remove warnings which may well be compiler figments, that's obviously
> ok.
>
> Linus
> -
There are some pretty scary macros like:
MIN(a, b) (a < b) ? a:b You can throw any parentheses you want
around and it doesn't make it correct for selecting the lowest value
of the amount to read/write from a buffer. The a and b need to be cast
to unsigned before the comparison is made --and then some compilers
will (correctly, I'm told) compain about range.
Cheers,
Dick Johnson
Penguin : Linux version 2.6.9 on an i686 machine (5537.79 BogoMips).
Notice : All mail here is now cached for review by John Ashcroft.
98.36% of all statistics are fiction.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-11-23 19:20 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-21 22:55 [PATCH] Remove pointless <0 comparison for unsigned variable in fs/fcntl.c Jesper Juhl
2004-11-22 1:02 ` Matthew Wilcox
2004-11-23 9:42 ` Jesper Juhl
2004-11-23 10:42 ` Jamie Lokier
2004-11-23 18:28 ` Bryan Henderson
2004-11-23 18:03 ` Linus Torvalds
2004-11-23 18:39 ` Jesper Juhl
2004-11-23 18:37 ` Linus Torvalds
2004-11-23 19:20 ` linux-os
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).