@@ -14,6 +14,7 @@ mod cast_sign_loss;
14
14
mod cast_slice_different_sizes;
15
15
mod cast_slice_from_raw_parts;
16
16
mod char_lit_as_u8;
17
+ mod dangling_ptr;
17
18
mod fn_to_numeric_cast;
18
19
mod fn_to_numeric_cast_any;
19
20
mod fn_to_numeric_cast_with_truncation;
@@ -754,6 +755,28 @@ declare_clippy_lint! {
754
755
"detects `as *mut _` and `as *const _` conversion"
755
756
}
756
757
758
+ declare_clippy_lint ! {
759
+ /// ### What it does
760
+ /// Catches casts from a positive integer literal to some pointer type
761
+ ///
762
+ /// ### Why is this bad?
763
+ /// This creates a pointer with no provenance which might cause incorrect compiler optimizations.
764
+ /// It is better expressed as {`std`, `core`}`::ptr::`{`dangling`, `dangling_mut`}.
765
+ ///
766
+ /// ### Example
767
+ /// ```no_run
768
+ /// let a = 1 as *const u32;
769
+ /// ```
770
+ /// Use instead:
771
+ /// ```no_run
772
+ /// let a = std::ptr::dangling::<u32>();
773
+ /// ```
774
+ #[ clippy:: version = "1.86.0" ]
775
+ pub DANGLING_PTR ,
776
+ pedantic,
777
+ "casting a positive integer literal to a pointer with no provenance"
778
+ }
779
+
757
780
pub struct Casts {
758
781
msrv : Msrv ,
759
782
}
@@ -792,6 +815,7 @@ impl_lint_pass!(Casts => [
792
815
ZERO_PTR ,
793
816
REF_AS_PTR ,
794
817
AS_POINTER_UNDERSCORE ,
818
+ DANGLING_PTR ,
795
819
] ) ;
796
820
797
821
impl < ' tcx > LateLintPass < ' tcx > for Casts {
@@ -819,6 +843,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
819
843
fn_to_numeric_cast:: check ( cx, expr, cast_from_expr, cast_from, cast_to) ;
820
844
fn_to_numeric_cast_with_truncation:: check ( cx, expr, cast_from_expr, cast_from, cast_to) ;
821
845
zero_ptr:: check ( cx, expr, cast_from_expr, cast_to_hir) ;
846
+ dangling_ptr:: check ( cx, expr, cast_from_expr, cast_to_hir) ;
822
847
823
848
if cast_to. is_numeric ( ) {
824
849
cast_possible_truncation:: check ( cx, expr, cast_from_expr, cast_from, cast_to, cast_to_hir. span ) ;
0 commit comments