-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Lint against getting pointers from immediately dropped temporaries #128985
base: master
Are you sure you want to change the base?
Lint against getting pointers from immediately dropped temporaries #128985
Conversation
r? @wesleywiser rustbot has assigned @wesleywiser. Use |
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.
This comment has been minimized.
This comment has been minimized.
FYI this probably needs T-lang approval and a crater run |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ddf0d12
to
34c4b17
Compare
This comment has been minimized.
This comment has been minimized.
34c4b17
to
f403c05
Compare
This probably needs a crater run. Check-only should suffice. However, the lint should probably be denied for the run, but I am not sure if crater has such an option. Maybe I will just temporary change the default level in code. Anyways, neither do I have permissions for |
tests/ui/lint/dangling-ptr/instantly-dangling-pointer-issue123613.rs
Outdated
Show resolved
Hide resolved
|
||
const MAX_PATH: usize = 260; | ||
fn main() { | ||
let str1 = String::with_capacity(MAX_PATH).as_mut_ptr(); |
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 wonder if it would make sense to suggest introducing a second binding in those simple let
cases, aka.
let str1 = String::with_capacity(MAX_PATH);
let str1 = str1.as_mut_ptr();
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.
Probably yes, but I would prefer to do this as a separate follow-up PR if possible
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 wonder if it would make sense to suggest introducing a second binding in those simple
let
cases, aka.let str1 = String::with_capacity(MAX_PATH); let str1 = str1.as_mut_ptr();
After looking at the "regressed" code from crater, I can say that a lot of the time this suggestion will not fix the problem, and will just result in code like
let vec = some_iter.collect();
let ptr = vec.as_ptr();
return ptr;
or similar where the pointer still dangles eventually, even though we binded the temporary for now.
Sometimes it would make sense to suggest things like .into_raw_parts()
instead of .as_ptr()
, but then the user has to remember to do ::from_raw_parts()
if they want to avoid leaking...
Most of the places where this lint fires are not trivial to fix and actually require the person writing the code to be more cautious & knowledgeable about what they are doing, which can only be achieved through more experience of writing unsafe
, as well as some punches from the compiler, miri, or sanitizers.
I think that not providing this suggestion in places where it would help is less bad than improperly providing it in places where it wouldn't help but would just further obscure and hide the issue.
This comment has been minimized.
This comment has been minimized.
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
This comment has been minimized.
This comment has been minimized.
Looks like this caught an actual mistake in miri tests. However, the test in question was added after this PR had been opened, so I will have to rebase now to be able to fix the test. |
8139b97
to
cb3d924
Compare
Rebased |
The Miri subtree was changed cc @rust-lang/miri |
It did. That's a good demo for the lint being quite useful indeed. :) |
This comment has been minimized.
This comment has been minimized.
1. Fix `is_temporary_rvalue` for: - Unary operations (such as dereference) - `yield` - Literals, array literals, repeat array literals - `DropTemps` 2. Fix typecheck to account for `T` in `Box<T>`
Turns out you cannot format Ty's you won't emit in unsuppressed diagnostics
The solution is hacky and itroduces more false negatives. Also added some docs and tests.
Sometimes we need to BOTH pop a `LifetimeExtension::Enable` AND change the now-top-of-the-stack `EnableLater` to `Enable` during the same `check_expr_post`.
ef400de
to
baaa2e0
Compare
Fixes #123613
Changes:
dangling_pointers_from_temporaries
. Is a generalization oftemporary_cstring_as_ptr
for more types and more ways to get a temporary.temporary_cstring_as_ptr
is removed and marked as renamed todangling_pointers_from_temporaries
.clippy::temporary_cstring_as_ptr
is marked as renamed todangling_pointers_from_temporaries
.core::cell::Cell
is nowrustc_diagnostic_item = "Cell"
Questions:
Known limitations:
False negatives2:
See the comments in
compiler/rustc_lint/src/dangling.rs
temporary_unsafe_cell.get()
temporary_sync_unsafe_cell.get()
owning_temporary.field
owning_temporary[index]
&raw [mut] temporary
&temporary as *(const|mut) _
ptr::from_ref(&temporary)
and friendsFootnotes
lint should not be emitted, but is ↩
lint should be emitted, but is not ↩