Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

false positive: a - b > b is not really an underflow check #2457

Closed
cuviper opened this issue Feb 13, 2018 · 5 comments · Fixed by #12944
Closed

false positive: a - b > b is not really an underflow check #2457

cuviper opened this issue Feb 13, 2018 · 5 comments · Fixed by #12944

Comments

@cuviper
Copy link
Member

cuviper commented Feb 13, 2018

In the original PR for overflow_check_conditional, I found this comment suggesting checks for subtraction: #741 (comment)

I agree with linting a - b > a -- there's no way for this to be true without underflow. You can also look at this algebraically, where this simplifies to 0 > b, which is nonsense for an unsigned type.

I disagree with linting a - b > b -- if you already know that a - b won't underflow (from a separate test or precondition), then this is a legitimate way of testing a > 2 * b, with the benefit of avoiding potential overflow in 2 * b.

One could alternately write this as a > b.saturating_mul(2) or a > b.saturating_add(b), but I tried this in one of my Project Euler solutions, and it was measurably slower. Even a raw a > 2 * b was slower than a - b > b!

Thoughts?

@cuviper
Copy link
Member Author

cuviper commented Feb 13, 2018

The performance difference is a tangent, but FWIW I explored this in godbolt. I think the key is that my code wants to return b in a filter_map, and the sub version maintains this value while using one less register (no ecx). I guess this could make a difference to register pressure in the larger inlined context? Not sure...

@bootandy
Copy link
Contributor

Your thoughts seems reasonable to me.

@ghost

This comment was marked as duplicate.

1 similar comment
@ghost
Copy link

ghost commented Sep 4, 2022

I also have a case where clippy marks:

if a + b < a {
    let new = a + b;
    // do something with `new`
}

But if I replace this with the following, as Clippy suggests:

let (new, overflow) = a.overflowing_add(b);
if !overflow {
    // do something with `new`
}

It actually changes the logic.

So yeah. I think something's wrong here.

@Bubbler-4
Copy link

I also got this lint today by typing if r < n - r and was puzzled as to how it could be an overflow check at all. r < n - r is more expressive than other equivalents in my situation because r represents one choice and n - r represents another.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants