@@ -43,13 +43,10 @@ declare_lint! {
4343}
4444
4545/// 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:
5047/// - `owning_temporary.field`
5148/// - `owning_temporary[index]`
52- /// 3 . No checks for ref-to-ptr conversions:
49+ /// 2 . No checks for ref-to-ptr conversions:
5350/// - `&raw [mut] temporary`
5451/// - `&temporary as *(const|mut) _`
5552/// - `ptr::from_ref(&temporary)` and friends
@@ -133,10 +130,11 @@ impl DanglingPointerSearcher<'_, '_> {
133130
134131fn lint_expr ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) {
135132 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)
137135 && is_temporary_rvalue ( receiver)
138136 && let ty = cx. typeck_results ( ) . expr_ty ( receiver)
139- && is_interesting ( cx. tcx , ty)
137+ && owns_allocation ( cx. tcx , ty)
140138 {
141139 // FIXME: use `emit_node_lint` when `#[primary_span]` is added.
142140 cx. tcx . emit_node_span_lint (
@@ -199,24 +197,25 @@ fn is_temporary_rvalue(expr: &Expr<'_>) -> bool {
199197 }
200198}
201199
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 {
205203 if ty. is_array ( ) {
206204 true
207205 } else if let Some ( inner) = ty. boxed_ty ( ) {
208206 inner. is_slice ( )
209207 || inner. is_str ( )
210208 || 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)
212210 } 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 ] {
214212 if tcx. is_lang_item ( def. did ( ) , lang_item) {
215213 return true ;
216214 }
217215 }
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+ } )
220219 } else {
221220 false
222221 }
0 commit comments