Uh oh!
There was an error while loading. Please reload this page.
Lint against getting pointers from immediately dropped temporaries - #128985
Conversation
rustbot
commented
Aug 11, 2024
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.
jieyouxu
commented
Aug 12, 2024
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
34c4b17Compare
This comment has been minimized.
This comment has been minimized.
34c4b17 to
f403c05CompareGrigorenkoPV
commented
Aug 12, 2024
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 |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| const MAX_PATH: usize = 260; | ||
| fn main() { | ||
| let str1 = String::with_capacity(MAX_PATH).as_mut_ptr(); |
There was a problem hiding this comment.
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.
Probably yes, but I would prefer to do this as a separate follow-up PR if possible
There was a problem hiding this comment.
I wonder if it would make sense to suggest introducing a second binding in those simple
letcases, 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.
There was a problem hiding this comment.
I still feel like we should point users towards doing something, even if it's not a general solution, and not a a structured suggestion.
It's really a shame to tell users something but not how to fix it.
Opened #132283 to track this.
There was a problem hiding this comment.
It's really a shame to tell users something but not how to fix it.
It's even worse to suggest something that is no a fix. So if you are sure you have a correct suggestion, then sure, please make it -- but never do this unless you are sure. People will trust the suggestion and then be worse off than before.
EDIT: Sorry, I should have posted in the issue. Here we go.
This comment has been minimized.
This comment has been minimized.
rustbot
commented
Aug 20, 2024
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
This comment has been minimized.
This comment has been minimized.
GrigorenkoPV
commented
Aug 21, 2024
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
cb3d924CompareGrigorenkoPV
commented
Aug 21, 2024
Rebased |
rustbot
commented
Aug 21, 2024
The Miri subtree was changed cc @rust-lang/miri |
Uh oh!
There was an error while loading. Please reload this page.
RalfJung
commented
Aug 21, 2024
It did. That's a good demo for the lint being quite useful indeed. :) |
This comment has been minimized.
This comment has been minimized.
rfcbot
commented
Oct 26, 2024
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) { | ||
| if let ExprKind::MethodCall(method, receiver, _args, _span) = expr.kind | ||
| && matches!(method.ident.name, sym::as_ptr | sym::as_mut_ptr) |
There was a problem hiding this comment.
If you want to do it in this PR (otherwise in a follow-up), we could add an rustc attribute to those as_ptr/as_mut_ptr methods.
You can follow afcb09b and 2a930d3 (from a PR of mine) with check_applied_to_fn_or_method instead, and something similar to this to check the attribute
rust/compiler/rustc_lint/src/ptr_nulls.rs
Lines 49 to 50 in e454c45
There was a problem hiding this comment.
I would prefer to do this as a follow-up, just not to stall this one any longer
There was a problem hiding this comment.
I've created #132281 to track the use of a rustc attr for this lint.
Feel free to assign it to your-self (@rustbot assign I think).
Uh oh!
There was an error while loading. Please reload this page.
78a0c89 to
c69894eCompare| .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 = for more information, see <https://doc.rust-lang.org/reference/destructors.html> |
There was a problem hiding this comment.
It's too bad that we don't have place explaining what a "dangling pointer" is, we could have linked it here.
Opened #132286 about that.
bors
commented
Oct 28, 2024
bors
commented
Oct 29, 2024
bors
commented
Oct 29, 2024
☀️ Test successful - checks-actions |
rust-timer
commented
Oct 29, 2024
Finished benchmarking commit (a9d1762): comparison URL. Overall result: ❌ regressions - no action needed@rustbot label: -perf-regression Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary 2.1%, secondary 4.0%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResults (secondary -3.0%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 782.325s -> 783.339s (0.13%) |
Fixes#123613
Changes:
dangling_pointers_from_temporaries. Is a generalization oftemporary_cstring_as_ptrfor more types and more ways to get a temporary.temporary_cstring_as_ptris removed and marked as renamed todangling_pointers_from_temporaries.clippy::temporary_cstring_as_ptris marked as renamed todangling_pointers_from_temporaries.core::cell::Cellis nowrustc_diagnostic_item = "Cell"Questions:
Known limitations:
False negatives2:
See the comments in
compiler/rustc_lint/src/dangling.rstemporary_unsafe_cell.get()temporary_sync_unsafe_cell.get()owning_temporary.fieldowning_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↩