]>
Commit | Line | Data |
---|---|---|
cdc7bbd5 XL |
1 | use clippy_utils::diagnostics::span_lint_and_help; |
2 | use clippy_utils::source::snippet; | |
3 | use if_chain::if_chain; | |
f20569fa XL |
4 | use rustc_hir::{Expr, ExprKind}; |
5 | use rustc_lint::{LateContext, LateLintPass}; | |
c295e0f8 | 6 | use rustc_middle::ty::layout::LayoutOf; |
f20569fa XL |
7 | use rustc_middle::ty::{self, ConstKind}; |
8 | use rustc_session::{declare_tool_lint, impl_lint_pass}; | |
9 | ||
f20569fa | 10 | declare_clippy_lint! { |
94222f64 XL |
11 | /// ### What it does |
12 | /// Checks for local arrays that may be too large. | |
f20569fa | 13 | /// |
94222f64 XL |
14 | /// ### Why is this bad? |
15 | /// Large local arrays may cause stack overflow. | |
f20569fa | 16 | /// |
94222f64 | 17 | /// ### Example |
f20569fa XL |
18 | /// ```rust,ignore |
19 | /// let a = [0u32; 1_000_000]; | |
20 | /// ``` | |
a2a8927a | 21 | #[clippy::version = "1.41.0"] |
f20569fa XL |
22 | pub LARGE_STACK_ARRAYS, |
23 | pedantic, | |
24 | "allocating large arrays on stack may cause stack overflow" | |
25 | } | |
26 | ||
27 | pub struct LargeStackArrays { | |
28 | maximum_allowed_size: u64, | |
29 | } | |
30 | ||
31 | impl LargeStackArrays { | |
32 | #[must_use] | |
33 | pub fn new(maximum_allowed_size: u64) -> Self { | |
34 | Self { maximum_allowed_size } | |
35 | } | |
36 | } | |
37 | ||
38 | impl_lint_pass!(LargeStackArrays => [LARGE_STACK_ARRAYS]); | |
39 | ||
40 | impl<'tcx> LateLintPass<'tcx> for LargeStackArrays { | |
41 | fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { | |
42 | if_chain! { | |
43 | if let ExprKind::Repeat(_, _) = expr.kind; | |
44 | if let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind(); | |
923072b8 FG |
45 | if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind(); |
46 | if let Ok(element_count) = element_count.try_to_machine_usize(cx.tcx); | |
5099ac24 | 47 | if let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes()); |
f20569fa XL |
48 | if self.maximum_allowed_size < element_count * element_size; |
49 | then { | |
50 | span_lint_and_help( | |
51 | cx, | |
52 | LARGE_STACK_ARRAYS, | |
53 | expr.span, | |
54 | &format!( | |
55 | "allocating a local array larger than {} bytes", | |
56 | self.maximum_allowed_size | |
57 | ), | |
58 | None, | |
59 | &format!( | |
60 | "consider allocating on the heap with `vec!{}.into_boxed_slice()`", | |
61 | snippet(cx, expr.span, "[...]") | |
62 | ), | |
63 | ); | |
64 | } | |
65 | } | |
66 | } | |
67 | } |