Write docs for lint / fix review nit
This commit is contained in:
parent
1bcd2452fe
commit
576eb2a30c
4 changed files with 25 additions and 8 deletions
|
@ -6,6 +6,25 @@ use rustc_middle::ty;
|
||||||
use rustc_span::{symbol::sym, ExpnKind, Span};
|
use rustc_span::{symbol::sym, ExpnKind, Span};
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
|
/// The `temporary_cstring_as_ptr` lint detects getting the inner pointer of
|
||||||
|
/// a temporary `CString`.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # #![allow(unused)]
|
||||||
|
/// let c_str = CString::new("foo").unwrap().as_ptr();
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// The inner pointer of a `CString` lives only as long as the `CString` it
|
||||||
|
/// points to. Getting the inner pointer of a *temporary* `CString` allows the `CString`
|
||||||
|
/// to be dropped at the end of the statement, as it is not being referenced as far as the typesystem
|
||||||
|
/// is concerned. This means outside of the statement the pointer will point to freed memory, which
|
||||||
|
/// causes undefined behavior if the pointer is later dereferenced.
|
||||||
pub TEMPORARY_CSTRING_AS_PTR,
|
pub TEMPORARY_CSTRING_AS_PTR,
|
||||||
Warn,
|
Warn,
|
||||||
"detects getting the inner pointer of a temporary `CString`"
|
"detects getting the inner pointer of a temporary `CString`"
|
||||||
|
@ -75,8 +94,7 @@ fn lint_cstring_as_ptr(
|
||||||
unwrap.span,
|
unwrap.span,
|
||||||
"this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime",
|
"this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime",
|
||||||
);
|
);
|
||||||
diag.note("pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement...");
|
diag.note("pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned");
|
||||||
diag.note("...because nothing is referencing it as far as the type system is concerned");
|
|
||||||
diag.help("for more information, see https://doc.rust-lang.org/reference/destructors.html");
|
diag.help("for more information, see https://doc.rust-lang.org/reference/destructors.html");
|
||||||
diag.emit();
|
diag.emit();
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,8 +11,7 @@ note: the lint level is defined here
|
||||||
|
|
|
|
||||||
LL | #![deny(temporary_cstring_as_ptr)]
|
LL | #![deny(temporary_cstring_as_ptr)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement...
|
= note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
|
||||||
= note: ...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
|
= help: for more information, see https://doc.rust-lang.org/reference/destructors.html
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// ignore-tidy-linelength
|
// ignore-tidy-linelength
|
||||||
|
// this program is not technically incorrect, but is an obscure enough style to be worth linting
|
||||||
#![deny(temporary_cstring_as_ptr)]
|
#![deny(temporary_cstring_as_ptr)]
|
||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: getting the inner pointer of a temporary `CString`
|
error: getting the inner pointer of a temporary `CString`
|
||||||
--> $DIR/lint-temporary-cstring-as-ptr.rs:7:48
|
--> $DIR/lint-temporary-cstring-as-ptr.rs:8:48
|
||||||
|
|
|
|
||||||
LL | let s = CString::new("some text").unwrap().as_ptr();
|
LL | let s = CString::new("some text").unwrap().as_ptr();
|
||||||
| ---------------------------------- ^^^^^^ this pointer will be invalid
|
| ---------------------------------- ^^^^^^ this pointer will be invalid
|
||||||
|
@ -7,12 +7,11 @@ LL | let s = CString::new("some text").unwrap().as_ptr();
|
||||||
| this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
| this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/lint-temporary-cstring-as-ptr.rs:2:9
|
--> $DIR/lint-temporary-cstring-as-ptr.rs:3:9
|
||||||
|
|
|
|
||||||
LL | #![deny(temporary_cstring_as_ptr)]
|
LL | #![deny(temporary_cstring_as_ptr)]
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement...
|
= note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
|
||||||
= note: ...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
|
= help: for more information, see https://doc.rust-lang.org/reference/destructors.html
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue