-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Transmuting known null ptr to ref #3848
Conversation
@flip1995 this is very much a WIP (the cool thing is that GH now lets me mark it as WIP ^^) I wanted to ask for your help: why do I get the following error? error[E0277]: the trait bound `for<'a, 'tcx> &'static rustc::lint::Lint: rustc::lint::LateLintPass<'a, 'tcx>` is not satisfied
--> clippy_lints/src/lib.rs:574:33
|
574 | reg.register_late_lint_pass(box transmuting_null::TRANSMUTING_NULL);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'tcx> rustc::lint::LateLintPass<'a, 'tcx>` is not implemented for `&'static rustc::lint::Lint`
|
= note: required for the cast to the object type `dyn for<'a, 'tcx> rustc::lint::LateLintPass<'a, 'tcx> + rustc_data_structures::sync::Send + rustc_data_structures::sync::Sync`
error: aborting due to previous error
I thought I'd copied everything relevant from another Late-Pass Lint, but clearly I've missed something ^^' |
I have now started work on the lint proper. I know how to identify a Any pointers on the book keeping idea would be appreciated. This is what I want to do:
Bonus question: if the variable is shadowed, would it matter? Would my reference to the variable being shadowed appear in subsequent checks? Thanks in advance. |
The |
I think I'm now catching all the one-liners. @flip1995 I now need your help on how to proceed with cases that span more than one statement :) |
Also please check my UI test, maybe I'm still lacking some examples of "known nulls": https://github.com/rust-lang/rust-clippy/pull/3848/files#diff-9c393f2ec14c6de7f3cc2117ba4b7514 |
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.
Before implementing all the cases by hand you should take a look at clippy_lints/src/constants.rs
. There should be a method which you should be able to call on the argument of the transmute
call. With a little bit of luck, this already covers all/most of the cases.
Please also push a WIP *.stderr file. This makes reviewing easier since I can see what already works directly.
Oh! Of course! I thought I might as well wait for completion before pushing it, given it's not ready yet. But I didn't think you might need it; it makes so much sense to me now. I'm gonna push it :) Edit: done ^^ |
You mean |
It would be this, right? |
Okay, this is what I have for multi-statement cases. I create a Maybe this particular evaluation hasn't been implemented yet? 🤔 fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
if_chain! {
if let ExprKind::Call(ref func, ref args) = expr.node;
if let ExprKind::Path(ref path) = func.node;
if match_qpath(path, &["std", "mem", "transmute"]);
if args.len() == 1;
then {
// Catching transmute over variables or constants
// that resolve to `null`
// FIXME: make it work
let mut const_eval_context = constant_context(cx, cx.tables);
if_chain! {
if let ExprKind::Path(ref qpath) = args[0].node;
then {
let x = const_eval_context.expr(&args[0]);
let s = format!("{:?}", x);
span_lint(
cx,
TRANSMUTING_NULL,
expr.span,
&s)
}
}
// Omitted the rest of the function because it's not relevant for this case |
I think it all amounts to the fact that in We're missing almost all of the cases. |
I think for the purposes of this PR, we're missing an implementation for the following variants of the
|
The |
I have pushed a change that lets you now evaluate a |
Also: the only thing we need at |
OTOH, this PR already should be able to catch:
If that's useful enough, we could merge what there is for now and wait for more |
Nevermind the Hir thing. I think the only thing we really need is a way to interpret the value of a |
About the error messages: Here the first three are actual linting triggers. The next one ( The last three are that, as well. But those three should trigger a lint, if we manage to interpret the value of a |
Thanks for doing all the work and the research! I'll take a closer look at this, this evening. The stderr looks good so far. It seems that the only thing left to do is to resolve local vars. |
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 took a closer look at this, but couldn't figure out how to handle the Local
case yet. I will take another look tomorrow.
For now you just get a nice to know:
Doing this with |
What do you mean? As in, with things like Btw regarding MIR and subsequent passes: we only intend to check things that the compiler is able to deduce are let zero : *const u64 = 0 as *const u64;
let zero_ts : &u64 = std::mem::transmute(zero); Into this, using constant propagation: let zero_ts : &u64 = std::mem::transmute(0 as *const u64); I was thinking that if that pass exists, then maybe we can run the lint after that pass, and check directly inside the
I'd say that depending on the APIs we have access to, I'm not against reimplementing some code. But if you say this, I imagine it's probably because it must be quite some work and it's not all that feasible.
In this context, is const folding what we've being doing? Or is it what I asked about in the paragraph above? (what I called "constant propagation") |
Yes, that's what would happen if we implemented this as a MIR lint. Basically right now we would only get |
Let's do that, then. What do I need to do in order to change this to a MIR lint? |
☔ The latest upstream changes (presumably #3767) made this pull request unmergeable. Please resolve the merge conflicts. |
Sadly there is no nice interface for MIR based lints, like there is for AST and HIR. (At least AFAIK @oli-obk ?) For now I would suggest to just do this with the HIR information we have available. |
In the last couple of days, I've been asking Oliver tons and tons of questions to understand what parts of MIR can be used here, and for what purposes :) With what I know now, I should be able to reimplement a bit of what I did already, making it work using the MIR tooling instead of the code present in The However, using the MIR tooling should leave the door open for future improvements coming for free from MIR itself to the lint. After the constant propagation optimization gets more stable there, it should even cover the We'll need a tracking issue (I assume at rustc's repo?) for the MIR opts, so that when those are ready, we can update the tests here to cover those cases. |
PS: it has been updated :) |
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.
Just the 2 small points above, a CI pass and this can get merged.
Ran |
Now that #3905 has been merged, we can re-run CI over this :) |
Aw dang, it failed on CI. Now I'm out of the computer, I'll go back to this if not tonight, tomorrow :) |
Yay, Travis passed! The PR is finally ready ^^ |
|
* Late Lint pass, catches: * One liner: 0 -> null -> transmute * One liner: std:null() -> transmute * Const (which resolves to null) -> transmute * UI Test case for Lint * Updated test for issue 3849, because now the lint that code generated is in Clippy. * Expanded `const.rs` miri-based Constant Folding code, to cover raw pointers
Done! |
Crap, because I don't understand how to update my I have deleted it. This PR seems to still work? But Github says the PR comes from "unkown repository". Please tell me if it still works, otherwise I'll make another branch and put my local copy of the PR into it 😱 Sorry for the inconvenience!! 🙇♂️ |
You can try If that doesn't work for some reason, have a look at this gist, too. |
@bors try (let's see if bors cares about the missing branch) |
Transmuting known null ptr to ref Working on implementing #628
☀️ Try build successful - checks-travis, status-appveyor |
@bors r+ |
📌 Commit 069957a has been approved by |
Transmuting known null ptr to ref Working on implementing #628
☀️ Test successful - checks-travis, status-appveyor |
⛵️ |
Working on implementing #628