]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/invalid_ref.rs
Merge pull request #2096 from lpesk/invalid-ref
[rust.git] / clippy_lints / src / invalid_ref.rs
1 use rustc::lint::*;
2 use rustc::ty;
3 use rustc::hir::*;
4 use utils::{match_def_path, paths, span_help_and_lint, opt_def_id};
5
6 /// **What it does:** Checks for creation of references to zeroed or uninitialized memory.
7 ///
8 /// **Why is this bad?** Creation of null references is undefined behavior.
9 ///
10 /// **Known problems:** None. 
11 ///
12 /// **Example:**
13 /// ```rust
14 /// let bad_ref: &usize = std::mem::zeroed();
15 /// ```
16
17 declare_lint! {
18     pub INVALID_REF,
19     Warn,
20     "creation of invalid reference"
21 }
22
23 const ZERO_REF_SUMMARY: &str = "reference to zeroed memory";
24 const UNINIT_REF_SUMMARY: &str = "reference to uninitialized memory";
25 const HELP: &str = "Creation of a null reference is undefined behavior; see https://doc.rust-lang.org/reference/behavior-considered-undefined.html"; 
26
27 pub struct InvalidRef; 
28
29 impl LintPass for InvalidRef {
30     fn get_lints(&self) -> LintArray {
31         lint_array!(INVALID_REF)
32     }
33 }
34
35 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidRef {
36     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
37         if_let_chain!{[
38             let ExprCall(ref path, ref args) = expr.node,
39             let ExprPath(ref qpath) = path.node,
40             args.len() == 0,
41             let ty::TyRef(..) = cx.tables.expr_ty(expr).sty, 
42             let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id)),
43         ], {
44             let msg = if match_def_path(cx.tcx, def_id, &paths::MEM_ZEROED) | match_def_path(cx.tcx, def_id, &paths::INIT) {
45                 ZERO_REF_SUMMARY
46             } else if match_def_path(cx.tcx, def_id, &paths::MEM_UNINIT) | match_def_path(cx.tcx, def_id, &paths::UNINIT) {
47                 UNINIT_REF_SUMMARY
48             } else {
49                 return;
50             };
51             span_help_and_lint(cx, INVALID_REF, expr.span, msg, HELP);
52         }}        
53         return;
54     }
55 }