]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/invalid_ref.rs
Allow empty lines in lint doc examples
[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, opt_def_id, paths, span_help_and_lint};
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 declare_lint! {
17     pub INVALID_REF,
18     Warn,
19     "creation of invalid reference"
20 }
21
22 const ZERO_REF_SUMMARY: &str = "reference to zeroed memory";
23 const UNINIT_REF_SUMMARY: &str = "reference to uninitialized memory";
24 const HELP: &str = "Creation of a null reference is undefined behavior; \
25                     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_chain! {
38             if let ExprCall(ref path, ref args) = expr.node;
39             if let ExprPath(ref qpath) = path.node;
40             if args.len() == 0;
41             if let ty::TyRef(..) = cx.tables.expr_ty(expr).sty;
42             if let Some(def_id) = opt_def_id(cx.tables.qpath_def(qpath, path.hir_id));
43             then {
44                 let msg = if match_def_path(cx.tcx, def_id, &paths::MEM_ZEROED) |
45                              match_def_path(cx.tcx, def_id, &paths::INIT)
46                 {
47                     ZERO_REF_SUMMARY
48                 } else if match_def_path(cx.tcx, def_id, &paths::MEM_UNINIT) |
49                           match_def_path(cx.tcx, def_id, &paths::UNINIT)
50                 {
51                     UNINIT_REF_SUMMARY
52                 } else {
53                     return;
54                 };
55                 span_help_and_lint(cx, INVALID_REF, expr.span, msg, HELP);
56             }
57         }
58         return;
59     }
60 }