@@ -63,30 +63,53 @@ declare_clippy_lint! {
63
63
/// arguments but are not marked `unsafe`.
64
64
///
65
65
/// ### Why is this bad?
66
- /// The function should probably be marked `unsafe`, since
67
- /// for an arbitrary raw pointer, there is no way of telling for sure if it is
68
- /// valid.
66
+ /// The function should almost definitely be marked `unsafe`, since for an
67
+ /// arbitrary raw pointer, there is no way of telling for sure if it is valid.
68
+ ///
69
+ /// In general, this lint should **never be disabled** unless it is definitely a
70
+ /// false positive (please submit an issue if so) since it breaks Rust's
71
+ /// soundness guarantees, directly exposing API users to potentially dangerous
72
+ /// program behavior. This is also true for internal APIs, as it is easy to leak
73
+ /// unsoundness.
74
+ ///
75
+ /// ### Context
76
+ /// In Rust, an `unsafe {...}` block is used to indicate that the code in that
77
+ /// section has been verified in some way that the compiler can not. For a
78
+ /// function that accepts a raw pointer then accesses the pointer's data, this is
79
+ /// generally impossible as the incoming pointer could point anywhere, valid or
80
+ /// not. So, the signature should be marked `unsafe fn`: this indicates that the
81
+ /// function's caller must provide some verification that the arguments it sends
82
+ /// are valid (and then call the function within an `unsafe` block).
69
83
///
70
84
/// ### Known problems
71
85
/// * It does not check functions recursively so if the pointer is passed to a
72
86
/// private non-`unsafe` function which does the dereferencing, the lint won't
73
- /// trigger.
87
+ /// trigger (false negative) .
74
88
/// * It only checks for arguments whose type are raw pointers, not raw pointers
75
89
/// got from an argument in some other way (`fn foo(bar: &[*const u8])` or
76
- /// `some_argument.get_raw_ptr()`).
90
+ /// `some_argument.get_raw_ptr()`) (false negative) .
77
91
///
78
92
/// ### Example
79
93
/// ```rust,ignore
80
94
/// pub fn foo(x: *const u8) {
81
95
/// println!("{}", unsafe { *x });
82
96
/// }
97
+ ///
98
+ /// // this call "looks" safe but will segfault or worse!
99
+ /// // foo(invalid_ptr);
83
100
/// ```
84
101
///
85
102
/// Use instead:
86
103
/// ```rust,ignore
87
104
/// pub unsafe fn foo(x: *const u8) {
88
105
/// println!("{}", unsafe { *x });
89
106
/// }
107
+ ///
108
+ /// // this would cause a compiler error for calling without `unsafe`
109
+ /// // foo(invalid_ptr);
110
+ ///
111
+ /// // sound call if the caller knows the pointer is valid
112
+ /// unsafe { foo(valid_ptr); }
90
113
/// ```
91
114
#[ clippy:: version = "pre 1.29.0" ]
92
115
pub NOT_UNSAFE_PTR_ARG_DEREF ,
0 commit comments