@@ -2648,6 +2648,96 @@ declare_lint! {
2648
2648
} ;
2649
2649
}
2650
2650
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
+
2651
2741
declare_lint ! {
2652
2742
/// The `const_evaluatable_unchecked` lint detects a generic constant used
2653
2743
/// in a type.
@@ -3101,6 +3191,8 @@ declare_lint_pass! {
3101
3191
UNSAFE_OP_IN_UNSAFE_FN ,
3102
3192
INCOMPLETE_INCLUDE ,
3103
3193
CENUM_IMPL_DROP_CAST ,
3194
+ FUZZY_PROVENANCE_CASTS ,
3195
+ LOSSY_PROVENANCE_CASTS ,
3104
3196
CONST_EVALUATABLE_UNCHECKED ,
3105
3197
INEFFECTIVE_UNSTABLE_TRAIT_IMPL ,
3106
3198
MUST_NOT_SUSPEND ,
0 commit comments