@@ -2648,6 +2648,96 @@ declare_lint! {
26482648 } ;
26492649}
26502650
2651+ declare_lint ! {
2652+ /// The `fuzzy_provenance_casts` lint detects an `as` cast between an integer
2653+ /// and a pointer.
2654+ ///
2655+ /// ### Example
2656+ ///
2657+ /// ```rust
2658+ /// #![feature(strict_provenance)]
2659+ /// #![warn(fuzzy_provenance_casts)]
2660+ ///
2661+ /// fn main() {
2662+ /// let _dangling = 16_usize as *const u8;
2663+ /// }
2664+ /// ```
2665+ ///
2666+ /// {{produces}}
2667+ ///
2668+ /// ### Explanation
2669+ ///
2670+ /// This lint is part of the strict provenance effort, see [issue #95228].
2671+ /// Casting an integer to a pointer is considered bad style, as a pointer
2672+ /// contains, besides the *address* also a *provenance*, indicating what
2673+ /// memory the pointer is allowed to read/write. Casting an integer, which
2674+ /// doesn't have provenance, to a pointer requires the compiler to assign
2675+ /// (guess) provenance. The compiler assigns "all exposed valid" (see the
2676+ /// docs of [`ptr::from_exposed_addr`] for more information about this
2677+ /// "exposing"). This penalizes the optimiser and is not well suited for
2678+ /// dynamic analysis/dynamic program verification (e.g. Miri or CHERI
2679+ /// platforms).
2680+ ///
2681+ /// It is much better to use [`ptr::with_addr`] instead to specify the
2682+ /// provenance you want. If using this function is not possible because the
2683+ /// code relies on exposed provenance then there is as an escape hatch
2684+ /// [`ptr::from_exposed_addr`].
2685+ ///
2686+ /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
2687+ /// [`ptr::with_addr`]: https://doc.rust-lang.org/core/ptr/fn.with_addr
2688+ /// [`ptr::from_exposed_addr`]: https://doc.rust-lang.org/core/ptr/fn.from_exposed_addr
2689+ pub FUZZY_PROVENANCE_CASTS ,
2690+ Allow ,
2691+ "a fuzzy integer to pointer cast is used" ,
2692+ @feature_gate = sym:: strict_provenance;
2693+ }
2694+
2695+ declare_lint ! {
2696+ /// The `lossy_provenance_casts` lint detects an `as` cast between a pointer
2697+ /// and an integer.
2698+ ///
2699+ /// ### Example
2700+ ///
2701+ /// ```rust
2702+ /// #![feature(strict_provenance)]
2703+ /// #![warn(lossy_provenance_casts)]
2704+ ///
2705+ /// fn main() {
2706+ /// let x: u8 = 37;
2707+ /// let _addr: usize = &x as *const u8 as usize;
2708+ /// }
2709+ /// ```
2710+ ///
2711+ /// {{produces}}
2712+ ///
2713+ /// ### Explanation
2714+ ///
2715+ /// This lint is part of the strict provenance effort, see [issue #95228].
2716+ /// Casting a pointer to an integer is a lossy operation, because beyond
2717+ /// just an *address* a pointer may be associated with a particular
2718+ /// *provenance*. This information is used by the optimiser and for dynamic
2719+ /// analysis/dynamic program verification (e.g. Miri or CHERI platforms).
2720+ ///
2721+ /// Since this cast is lossy, it is considered good style to use the
2722+ /// [`ptr::addr`] method instead, which has a similar effect, but doesn't
2723+ /// "expose" the pointer provenance. This improves optimisation potential.
2724+ /// See the docs of [`ptr::addr`] and [`ptr::expose_addr`] for more information
2725+ /// about exposing pointer provenance.
2726+ ///
2727+ /// If your code can't comply with strict provenance and needs to expose
2728+ /// the provenance, then there is [`ptr::expose_addr`] as an escape hatch,
2729+ /// which preserves the behaviour of `as usize` casts while being explicit
2730+ /// about the semantics.
2731+ ///
2732+ /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
2733+ /// [`ptr::addr`]: https://doc.rust-lang.org/core/ptr/fn.addr
2734+ /// [`ptr::expose_addr`]: https://doc.rust-lang.org/core/ptr/fn.expose_addr
2735+ pub LOSSY_PROVENANCE_CASTS ,
2736+ Allow ,
2737+ "a lossy pointer to integer cast is used" ,
2738+ @feature_gate = sym:: strict_provenance;
2739+ }
2740+
26512741declare_lint ! {
26522742 /// The `const_evaluatable_unchecked` lint detects a generic constant used
26532743 /// in a type.
@@ -3101,6 +3191,8 @@ declare_lint_pass! {
31013191 UNSAFE_OP_IN_UNSAFE_FN ,
31023192 INCOMPLETE_INCLUDE ,
31033193 CENUM_IMPL_DROP_CAST ,
3194+ FUZZY_PROVENANCE_CASTS ,
3195+ LOSSY_PROVENANCE_CASTS ,
31043196 CONST_EVALUATABLE_UNCHECKED ,
31053197 INEFFECTIVE_UNSTABLE_TRAIT_IMPL ,
31063198 MUST_NOT_SUSPEND ,
0 commit comments