@@ -43,13 +43,10 @@ declare_lint! {
43
43
}
44
44
45
45
/// FIXME: false negatives (i.e. the lint is not emitted when it should be)
46
- /// 1. Method calls that are not checked for:
47
- /// - [`temporary_unsafe_cell.get()`][`core::cell::UnsafeCell::get()`]
48
- /// - [`temporary_sync_unsafe_cell.get()`][`core::cell::SyncUnsafeCell::get()`]
49
- /// 2. Ways to get a temporary that are not recognized:
46
+ /// 1. Ways to get a temporary that are not recognized:
50
47
/// - `owning_temporary.field`
51
48
/// - `owning_temporary[index]`
52
- /// 3 . No checks for ref-to-ptr conversions:
49
+ /// 2 . No checks for ref-to-ptr conversions:
53
50
/// - `&raw [mut] temporary`
54
51
/// - `&temporary as *(const|mut) _`
55
52
/// - `ptr::from_ref(&temporary)` and friends
@@ -133,10 +130,11 @@ impl DanglingPointerSearcher<'_, '_> {
133
130
134
131
fn lint_expr ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
135
132
if let ExprKind :: MethodCall ( method, receiver, _args, _span) = expr. kind
136
- && matches ! ( method. ident. name, sym:: as_ptr | sym:: as_mut_ptr)
133
+ && let Some ( fn_id) = cx. typeck_results ( ) . type_dependent_def_id ( expr. hir_id )
134
+ && cx. tcx . has_attr ( fn_id, sym:: rustc_as_ptr)
137
135
&& is_temporary_rvalue ( receiver)
138
136
&& let ty = cx. typeck_results ( ) . expr_ty ( receiver)
139
- && is_interesting ( cx. tcx , ty)
137
+ && owns_allocation ( cx. tcx , ty)
140
138
{
141
139
// FIXME: use `emit_node_lint` when `#[primary_span]` is added.
142
140
cx. tcx . emit_node_span_lint (
@@ -199,24 +197,25 @@ fn is_temporary_rvalue(expr: &Expr<'_>) -> bool {
199
197
}
200
198
}
201
199
202
- // Array, Vec, String, CString, MaybeUninit, Cell, Box<[_]>, Box<str>, Box<CStr>,
203
- // or any of the above in arbitrary many nested Box'es.
204
- fn is_interesting ( tcx : TyCtxt < ' _ > , ty : Ty < ' _ > ) -> bool {
200
+ // Array, Vec, String, CString, MaybeUninit, Cell, Box<[_]>, Box<str>, Box<CStr>, UnsafeCell,
201
+ // SyncUnsafeCell, or any of the above in arbitrary many nested Box'es.
202
+ fn owns_allocation ( tcx : TyCtxt < ' _ > , ty : Ty < ' _ > ) -> bool {
205
203
if ty. is_array ( ) {
206
204
true
207
205
} else if let Some ( inner) = ty. boxed_ty ( ) {
208
206
inner. is_slice ( )
209
207
|| inner. is_str ( )
210
208
|| inner. ty_adt_def ( ) . is_some_and ( |def| tcx. is_lang_item ( def. did ( ) , LangItem :: CStr ) )
211
- || is_interesting ( tcx, inner)
209
+ || owns_allocation ( tcx, inner)
212
210
} else if let Some ( def) = ty. ty_adt_def ( ) {
213
- for lang_item in [ LangItem :: String , LangItem :: MaybeUninit ] {
211
+ for lang_item in [ LangItem :: String , LangItem :: MaybeUninit , LangItem :: UnsafeCell ] {
214
212
if tcx. is_lang_item ( def. did ( ) , lang_item) {
215
213
return true ;
216
214
}
217
215
}
218
- tcx. get_diagnostic_name ( def. did ( ) )
219
- . is_some_and ( |name| matches ! ( name, sym:: cstring_type | sym:: Vec | sym:: Cell ) )
216
+ tcx. get_diagnostic_name ( def. did ( ) ) . is_some_and ( |name| {
217
+ matches ! ( name, sym:: cstring_type | sym:: Vec | sym:: Cell | sym:: SyncUnsafeCell )
218
+ } )
220
219
} else {
221
220
false
222
221
}
0 commit comments