-
Notifications
You must be signed in to change notification settings - Fork 13.9k
dangling pointer from temp cleanup #148490
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
Open
hkBst
wants to merge
1
commit into
rust-lang:master
Choose a base branch
from
hkBst:dangling-ptr-lint-2
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+355
−333
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -197,15 +197,17 @@ lint_dangling_pointers_from_locals = {$fn_kind} returns a dangling pointer to dr | |||||
| .ret_ty = return type is `{$ret_ty}` | ||||||
| .local_var = local variable `{$local_var_name}` is dropped at the end of the {$fn_kind} | ||||||
| .created_at = dangling pointer created here | ||||||
| .note = a dangling pointer is safe, but dereferencing one is undefined behavior | ||||||
|
|
||||||
| lint_dangling_pointers_from_temporaries = a dangling pointer will be produced because the temporary `{$ty}` will be dropped | ||||||
| .label_ptr = this pointer will immediately be invalid | ||||||
| .label_temporary = this `{$ty}` is deallocated at the end of the statement, bind it to a variable to extend its lifetime | ||||||
| .note = pointers do not have a lifetime; when calling `{$callee}` the `{$ty}` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned | ||||||
| .help_bind = you must make sure that the variable you bind the `{$ty}` to lives at least as long as the pointer returned by the call to `{$callee}` | ||||||
| .help_returned = in particular, if this pointer is returned from the current function, binding the `{$ty}` inside the function will not suffice | ||||||
| .help_visit = for more information, see <https://doc.rust-lang.org/reference/destructors.html> | ||||||
| .note_safe = a dangling pointer is safe, but dereferencing one is undefined behavior | ||||||
| .note_more_info = for more information, see <https://doc.rust-lang.org/reference/destructors.html> | ||||||
|
|
||||||
| lint_dangling_pointers_from_temporaries = expression creates a dangling pointer to dropped temporary `{$ty}` | ||||||
| .label_ptr = dangling pointer created here | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also is misleading IMO, it's not yet dangling but it will be. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| .label_temporary = this `{$ty}` is dropped at the end of the statement | ||||||
| .help_bind = bind the `{$ty}` to a variable such that it outlives the pointer returned by `{$callee}` | ||||||
| .note_safe = a dangling pointer is safe, but dereferencing one is undefined behavior | ||||||
| .note_return = returning a pointer to a local variable will always result in a dangling pointer | ||||||
| .note_more_info = for more information, see <https://doc.rust-lang.org/reference/destructors.html> | ||||||
|
|
||||||
|
|
||||||
| lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better performance | ||||||
| .note = a `use rustc_data_structures::fx::{$preferred}` may be necessary | ||||||
|
|
||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 14 additions & 14 deletions
28
tests/ui/lint/dangling-pointers-from-temporaries/allow.stderr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
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'm not sure that's the a good description of the issue, I feel like it's a bit misleading, the temporary is not yet dropped (otherwise this would insta UB), it's dropped only after creating the pointer, and it's the dropping of the temporary which makes the pointer dangling.
The previously wording was clearer IMO on this point. Not sure how to best improve that.
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.
Hmm, I thought that detail did not matter. Do you have a reference for your claim that that would be insta UB?
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.
For
String::new().DROPPED.as_ptr()it's apparently a grey area rust-lang/unsafe-code-guidelines#188 where use-after-dropped and use-after-free are different regarding opsem. I was told that it should probably be UB and is heavily discouraged.But for allocation like
"".to_string().DROPPED.as_ptr()Miri flags it as UB1 on theas_ptr()call, so 🤷Footnotes
https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=1c4f3446888f2b92d486a5f478722640 ↩
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 created rust-lang/miri#4668 to hopefully clarify this...
Uh oh!
There was an error while loading. Please reload this page.
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.
Right, so this is UB because of a dangling reference (which miri calls a pointer confusingly). I think the existence of https://doc.rust-lang.org/nightly/std/ptr/fn.dangling.html proves that just a dangling pointer is not UB.
I also think that means that it does not really matter whether a now-dangling pointer was temporarily valid at its point of creation.
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.
My un-easeness is not on whenever the pointer was temporarily valid, it is, but as you said it's not relevant. What I'm having problem with that your proposed message makes it ambiguous as to whenever or not the pointer was created from an invalid temporary, which rust-lang/miri#4668 made it clear that it's UB (lang or libs).
It would be IMO better if the message made it clear / obvious that the pointer is dangling precisely because it points to a temporary that's dropped too early, which the previous message was clearer about.
Maybe we could say something like this:
Uh oh!
There was an error while loading. Please reload this page.
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.
Or maybe something like this:
warning: this pointer becomes dangling as the temporary {$ty} is dropped at statement endAfter reflection I think I like this one the best, with the caveat that we should change the primary span to the
as_ptr()partUh oh!
There was an error while loading. Please reload this page.
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.
My interpretation is that it makes it clear that a dangling reference is UB, but a dangling pointer is fine either way...
"an
&stris created pointing to the deallocated buffer, " -> UB dangling reference (We use "pointer" as a term that encompasses both references and raw pointers )"using a reference to a dropped string" -> UB (not sure why it should be library UB and not language UB)
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 don't think I ever disputed the fact that a dangling pointer is fine unless dereferenced.
As I said earlier the wording should not in anyway make it seems like the dangling pointer is created from a dropped temporary, the pointer is created from a valid (not-dropped) temporary, it's only after the temporary is dropped (so after a call to
as_ptr) that the pointer becomes dangling.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.
You still seem to be arguing as if a dangling pointer created from a previously dropped temporary is UB, but that is like saying that creating a pointer from a random address is UB, which it clearly isn't, since there is no
unsafehere and it compiles fine:So if a dangling pointer is fine either way (unless deref'ed), then why bother making the distinction?