-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Implement new lint for detecting buggy pointer-to-int casts #81789
Conversation
r? @varkor (rust-highfive has picked a reviewer for you, use r? to override) |
☔ The latest upstream changes (presumably #79078) made this pull request unmergeable. Please resolve the merge conflicts. |
@osa1: are you waiting for this to be reviewed, or is it not ready yet? (I assumed you were still working on it because it was marked as a draft, but now I realise this might not be the case.) |
Hi @varkor -- sorry for late reply. This is ready for reviews. Note that the lint is not enabled by default, I'm guessing we want to enable it by default before shipping, right? I realize I didn't add a test -- I'll do that now. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks pretty good so far! I just have a few comments about wording, to try to make it a little clearer for users.
/// To cast a pointer to e.g. u32 without triggering the lint, first cast to usize: | ||
/// `ptr as usize as u32`. | ||
pub PTR_TO_INT_CAST, | ||
Allow, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that the lint is not enabled by default, I'm guessing we want to enable it by default before shipping, right?
I think it would be reasonable to make this Warn
by default. We'll also need to get the lang team to sign off on the new lint; I'll ping them once this is ready.
This comment has been minimized.
This comment has been minimized.
Hm, it seems like the check is not quite right. This program doesn't generate a warning: fn main() {
fn test() {}
let x: u16 = ({
test
}) as u16;
} |
Figured it out, update coming. |
This comment has been minimized.
This comment has been minimized.
@varkor should be ready now. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Ping @varkor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is mostly looking good now. Could you address the one comment, and squash your commits (or tidy them up a bit, e.g. there shouldn't be fixup or merge commits)?
@varkor all done. |
I made the lint deny-by-default, for the crater run. |
@bors try |
⌛ Trying commit 81df07d with merge 7b3565da729099dbe807466fcd118fb2815986e0... |
The job Click to see the possible cause of the failure (guessed by this bot)
|
Can I skip the compiler tests before the crater run somehow? I don't want to update all these tests just to run crater with the lint is denied by default. |
The failed job is one of the PR CI jobs. Try builds still succeed if tests are failing as far as I know. |
☀️ Try build successful - checks-actions |
@craterbot check |
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
3 days and the job is still in the queue? 😲 |
@osa1: crater takes a while to complete (it has to compile all the crates on cargo.io), and the queue is quite busy at the moment. |
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
🎉 Experiment
|
@rust-lang/lang discussed this again recently. We felt fairly hesitant about adding this lint. When we discussed previously, there was consensus that we did not want to lint on pointer -> There are a number of related issues occurring:
As far as I can tell, it seems like the primary issue described in #81686 is (1) and maybe (2). This PR seems to primarily address (4), with the side effect that some (but not all) instances of 1-3 are also detected. It feels like the lint in this PR as-implemented is likely to introduce a number of false positives (I really did want to store that pointer in a u32), yet a number of the cases in the original bug are not detected (e.g. Personally, I feel like this issue is another reason why we should offer convenient and ergonomic replacements for |
I think #81686 describes (2), not (1). Quoting the original issue:
However, what the issue describes may not matter too much, we may still want to provide a lint for casting function items/pointers to integer types when it will obviously overflow. We already do this for some other cases, for example: fn main() {
let x: u32 = u32::MAX + 1;
} generates
It seems inconsistent to not do the same check when casting a pointer to a smaller integer type.
Could you say more about your use case? Is this on a 32-bit platform?
We could detect this case as well. It was originally detected, but removed per @joshtriplett's request: #81789 (comment) |
As I say above, I think this lint makes sense regardless what you think #81686 is about, but if the language team disagrees then please feel free to close this PR, or let me know and I will close it. |
We discussed this again in the @rust-lang/lang meeting this week. We didn't come to a clear consensus, though, so what I'm posting here is a proposal for a direction to take this, not anything final or signed-off. I propose that we move forward with this lint, but remove the "Fixes #81686" from the OP. That would mean that this lint becomes just about general pointer truncation, and another PR would target that issue more specifically. That means that this lint will not solve the I think that also implies a few changes here. For example, the crater run shows a bunch of errors from casting to |
I'm curious about this statement by @cramertj:
This seems like the important question! I can imagine this comes up because of portability (e.g., when targeting 32-bit systems), but I'm not sure if there are other times when people really do want to store pointers into a u32 (which of course remains an option, but more awkward). |
We discussed this in the last lang team meeting. We noted that:
We didn't discuss next steps too concretely, but it feels like it might be good for someone to propose a PR adding to and from_bits to r? @joshtriplett for now as you've been driving this the most I think |
We discussed this in today's @rust-lang/lang meeting, as well as last week's @rust-lang/libs meeting. In @rust-lang/lang, our consensus was that we'd love to see In @rust-lang/libs, our consensus was that we'd be happy to take proposals for functions that serve the function of @rust-lang/libs also expressed the sentiment that We're going to close this PR, as we don't think we're going to accept this precisely as written. We'd be thrilled to see functions proposed to libs, and then corresponding lints proposed to lang to use those functions rather than |
To clarify: we'd be happy to see some version of this lint, and we think there's value in catching issues like this; we'd be happy to see this reopened and updated when there are methods that it can suggest. |
Fixes #81686