Split fuzzy_provenance_casts
into lossy and fuzzy, feature gate and test it
* split `fuzzy_provenance_casts` into a ptr2int and a int2ptr lint * feature gate both lints * update documentation to be more realistic short term * add tests for these lints
This commit is contained in:
parent
1040cab53b
commit
98a4834237
11 changed files with 281 additions and 35 deletions
|
@ -2654,9 +2654,12 @@ declare_lint! {
|
|||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(strict_provenance)]
|
||||
/// #![warn(fuzzy_provenance_casts)]
|
||||
///
|
||||
/// fn main() {
|
||||
/// let my_ref = &0;
|
||||
/// let my_addr = my_ref as usize;
|
||||
/// let _dangling = 16_usize as *const u8;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
|
@ -2664,23 +2667,75 @@ declare_lint! {
|
|||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// Casting a pointer to an integer or an integer to a pointer is a lossy operation,
|
||||
/// because beyond just an *address* a pointer may be associated with a particular
|
||||
/// *provenance* and *segment*. This information is required by both the compiler
|
||||
/// and the hardware to correctly execute your code. If you need to do this kind
|
||||
/// of operation, use ptr::addr and ptr::with_addr.
|
||||
/// This lint is part of the strict provenance effort, see [issue #95228].
|
||||
/// Casting an integer to a pointer is considered bad style, as a pointer
|
||||
/// contains, besides the *address* also a *provenance*, indicating what
|
||||
/// memory the pointer is allowed to read/write. Casting an integer, which
|
||||
/// doesn't have provenance, to a pointer requires the compiler to assign
|
||||
/// (guess) provenance. The compiler assigns "all exposed valid" (see the
|
||||
/// docs of [`ptr::from_exposed_addr`] for more information about this
|
||||
/// "exposing"). This penalizes the optimiser and is not well suited for
|
||||
/// dynamic analysis/dynamic program verification (e.g. Miri or CHERI
|
||||
/// platforms).
|
||||
///
|
||||
/// This is a [future-incompatible] lint to transition this to a hard error
|
||||
/// in the future. See [issue #9999999] for more details.
|
||||
/// It is much better to use [`ptr::with_addr`] instead to specify the
|
||||
/// provenance you want. If using this function is not possible because the
|
||||
/// code relies on exposed provenance then there is as an escape hatch
|
||||
/// [`ptr::from_exposed_addr`].
|
||||
///
|
||||
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
||||
/// [issue #9999999]: https://github.com/rust-lang/rust/issues/9999999
|
||||
/// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
|
||||
/// [`ptr::with_addr`]: https://doc.rust-lang.org/core/ptr/fn.with_addr
|
||||
/// [`ptr::from_exposed_addr`]: https://doc.rust-lang.org/core/ptr/fn.from_exposed_addr
|
||||
pub FUZZY_PROVENANCE_CASTS,
|
||||
Warn,
|
||||
"A lossy pointer-integer integer cast is used",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reference: "issue #9999999 <https://github.com/rust-lang/rust/issues/9999999>",
|
||||
};
|
||||
Allow,
|
||||
"a fuzzy integer to pointer cast is used",
|
||||
@feature_gate = sym::strict_provenance;
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `lossy_provenance_casts` lint detects an `as` cast between a pointer
|
||||
/// and an integer.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(strict_provenance)]
|
||||
/// #![warn(lossy_provenance_casts)]
|
||||
///
|
||||
/// fn main() {
|
||||
/// let x: u8 = 37;
|
||||
/// let _addr: usize = &x as *const u8 as usize;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// This lint is part of the strict provenance effort, see [issue #95228].
|
||||
/// Casting a pointer to an integer is a lossy operation, because beyond
|
||||
/// just an *address* a pointer may be associated with a particular
|
||||
/// *provenance*. This information is used by the optimiser and for dynamic
|
||||
/// analysis/dynamic program verification (e.g. Miri or CHERI platforms).
|
||||
///
|
||||
/// Since this cast is lossy, it is considered good style to use the
|
||||
/// [`ptr::addr`] method instead, which has a similar effect, but doesn't
|
||||
/// "expose" the pointer provenance. This improves optimisation potential.
|
||||
/// See the docs of [`ptr::addr`] and [`ptr::expose_addr`] for more information
|
||||
/// about exposing pointer provenance.
|
||||
///
|
||||
/// If your code can't comply with strict provenance and needs to expose
|
||||
/// the provenance, then there is [`ptr::expose_addr`] as an escape hatch,
|
||||
/// which preserves the behaviour of `as usize` casts while being explicit
|
||||
/// about the semantics.
|
||||
///
|
||||
/// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
|
||||
/// [`ptr::addr`]: https://doc.rust-lang.org/core/ptr/fn.addr
|
||||
/// [`ptr::expose_addr`]: https://doc.rust-lang.org/core/ptr/fn.expose_addr
|
||||
pub LOSSY_PROVENANCE_CASTS,
|
||||
Allow,
|
||||
"a lossy pointer to integer cast is used",
|
||||
@feature_gate = sym::strict_provenance;
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
|
@ -3137,6 +3192,7 @@ declare_lint_pass! {
|
|||
INCOMPLETE_INCLUDE,
|
||||
CENUM_IMPL_DROP_CAST,
|
||||
FUZZY_PROVENANCE_CASTS,
|
||||
LOSSY_PROVENANCE_CASTS,
|
||||
CONST_EVALUATABLE_UNCHECKED,
|
||||
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
|
||||
MUST_NOT_SUSPEND,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue