diff options
| author | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2024-10-16 22:19:56 +0300 |
|---|---|---|
| committer | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2024-10-28 14:16:05 +0300 |
| commit | c69894eaec2a29f9db023cbfff63e48266de4ee5 (patch) | |
| tree | 503a18333c8b8f4a1d968c28154f4c3942df67db /compiler/rustc_lint/src/methods.rs | |
| parent | 81d6652e741f091f4ee0b7a660120d204e0417b8 (diff) | |
| download | rust-c69894eaec2a29f9db023cbfff63e48266de4ee5.tar.gz rust-c69894eaec2a29f9db023cbfff63e48266de4ee5.zip | |
New lint: `dangling_pointers_from_temporaries`
Diffstat (limited to 'compiler/rustc_lint/src/methods.rs')
| -rw-r--r-- | compiler/rustc_lint/src/methods.rs | 69 |
1 files changed, 0 insertions, 69 deletions
diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs deleted file mode 100644 index df22bf0972d..00000000000 --- a/compiler/rustc_lint/src/methods.rs +++ /dev/null @@ -1,69 +0,0 @@ -use rustc_hir::{Expr, ExprKind}; -use rustc_middle::ty; -use rustc_session::{declare_lint, declare_lint_pass}; -use rustc_span::Span; -use rustc_span::symbol::sym; - -use crate::lints::CStringPtr; -use crate::{LateContext, LateLintPass, LintContext}; - -declare_lint! { - /// The `temporary_cstring_as_ptr` lint detects getting the inner pointer of - /// a temporary `CString`. - /// - /// ### Example - /// - /// ```rust - /// # #![allow(unused)] - /// # use std::ffi::CString; - /// let c_str = CString::new("foo").unwrap().as_ptr(); - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The inner pointer of a `CString` lives only as long as the `CString` it - /// points to. Getting the inner pointer of a *temporary* `CString` allows the `CString` - /// to be dropped at the end of the statement, as it is not being referenced as far as the - /// typesystem is concerned. This means outside of the statement the pointer will point to - /// freed memory, which causes undefined behavior if the pointer is later dereferenced. - pub TEMPORARY_CSTRING_AS_PTR, - Warn, - "detects getting the inner pointer of a temporary `CString`" -} - -declare_lint_pass!(TemporaryCStringAsPtr => [TEMPORARY_CSTRING_AS_PTR]); - -impl<'tcx> LateLintPass<'tcx> for TemporaryCStringAsPtr { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if let ExprKind::MethodCall(as_ptr_path, as_ptr_receiver, ..) = expr.kind - && as_ptr_path.ident.name == sym::as_ptr - && let ExprKind::MethodCall(unwrap_path, unwrap_receiver, ..) = as_ptr_receiver.kind - && (unwrap_path.ident.name == sym::unwrap || unwrap_path.ident.name == sym::expect) - { - lint_cstring_as_ptr(cx, as_ptr_path.ident.span, unwrap_receiver, as_ptr_receiver); - } - } -} - -fn lint_cstring_as_ptr( - cx: &LateContext<'_>, - as_ptr_span: Span, - source: &rustc_hir::Expr<'_>, - unwrap: &rustc_hir::Expr<'_>, -) { - let source_type = cx.typeck_results().expr_ty(source); - if let ty::Adt(def, args) = source_type.kind() { - if cx.tcx.is_diagnostic_item(sym::Result, def.did()) { - if let ty::Adt(adt, _) = args.type_at(0).kind() { - if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) { - cx.emit_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, CStringPtr { - as_ptr: as_ptr_span, - unwrap: unwrap.span, - }); - } - } - } - } -} |
