Skip to content

Commit faad9a1

Browse files
committed
Add more functions to size_of_in_element_count
Specifically ptr::{sub, wrapping_sub, add, wrapping_add, offset, wrapping_offset} and slice::{from_raw_parts, from_raw_parts_mut} The lint now also looks for size_of calls through casts (Since offset takes an isize)
1 parent 785d81b commit faad9a1

File tree

5 files changed

+126
-39
lines changed

5 files changed

+126
-39
lines changed

clippy_lints/src/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
828828
&shadow::SHADOW_SAME,
829829
&shadow::SHADOW_UNRELATED,
830830
&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
831+
&size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
831832
&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
832833
&stable_sort_primitive::STABLE_SORT_PRIMITIVE,
833834
&strings::STRING_ADD,
@@ -897,7 +898,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
897898
&unnecessary_wraps::UNNECESSARY_WRAPS,
898899
&unnested_or_patterns::UNNESTED_OR_PATTERNS,
899900
&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
900-
&size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
901901
&unused_io_amount::UNUSED_IO_AMOUNT,
902902
&unused_self::UNUSED_SELF,
903903
&unused_unit::UNUSED_UNIT,
@@ -1550,6 +1550,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
15501550
LintId::of(&self_assignment::SELF_ASSIGNMENT),
15511551
LintId::of(&serde_api::SERDE_API_MISUSE),
15521552
LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
1553+
LintId::of(&size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
15531554
LintId::of(&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
15541555
LintId::of(&stable_sort_primitive::STABLE_SORT_PRIMITIVE),
15551556
LintId::of(&strings::STRING_FROM_UTF8_AS_BYTES),
@@ -1596,7 +1597,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
15961597
LintId::of(&unnecessary_sort_by::UNNECESSARY_SORT_BY),
15971598
LintId::of(&unnecessary_wraps::UNNECESSARY_WRAPS),
15981599
LintId::of(&unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
1599-
LintId::of(&size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
16001600
LintId::of(&unused_io_amount::UNUSED_IO_AMOUNT),
16011601
LintId::of(&unused_unit::UNUSED_UNIT),
16021602
LintId::of(&unwrap::PANICKING_UNWRAP),
@@ -1859,6 +1859,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
18591859
LintId::of(&regex::INVALID_REGEX),
18601860
LintId::of(&self_assignment::SELF_ASSIGNMENT),
18611861
LintId::of(&serde_api::SERDE_API_MISUSE),
1862+
LintId::of(&size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
18621863
LintId::of(&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
18631864
LintId::of(&suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
18641865
LintId::of(&swap::ALMOST_SWAPPED),
@@ -1874,7 +1875,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
18741875
LintId::of(&unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
18751876
LintId::of(&unnamed_address::FN_ADDRESS_COMPARISONS),
18761877
LintId::of(&unnamed_address::VTABLE_ADDRESS_COMPARISONS),
1877-
LintId::of(&size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
18781878
LintId::of(&unused_io_amount::UNUSED_IO_AMOUNT),
18791879
LintId::of(&unwrap::PANICKING_UNWRAP),
18801880
LintId::of(&vec_resize_to_zero::VEC_RESIZE_TO_ZERO),

clippy_lints/src/size_of_in_element_count.rs

+27-17
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,36 @@ fn get_size_of_ty(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<Ty<'tc
5454
ExprKind::Binary(op, left, right) if BinOpKind::Mul == op.node || BinOpKind::Div == op.node => {
5555
get_size_of_ty(cx, left).or_else(|| get_size_of_ty(cx, right))
5656
},
57+
ExprKind::Cast(expr, _) => get_size_of_ty(cx, expr),
5758
_ => None,
5859
}
5960
}
6061

61-
const FUNCTIONS: [[&str; 3]; 6] = [
62-
paths::COPY_NONOVERLAPPING,
63-
paths::COPY,
64-
paths::WRITE_BYTES,
65-
paths::PTR_SWAP_NONOVERLAPPING,
66-
paths::PTR_SLICE_FROM_RAW_PARTS,
67-
paths::PTR_SLICE_FROM_RAW_PARTS_MUT,
62+
fn get_pointee_ty_and_count_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<(Ty<'tcx>, &'tcx Expr<'tcx>)> {
63+
const FUNCTIONS: [&[&str]; 8] = [
64+
&paths::COPY_NONOVERLAPPING,
65+
&paths::COPY,
66+
&paths::WRITE_BYTES,
67+
&paths::PTR_SWAP_NONOVERLAPPING,
68+
&paths::PTR_SLICE_FROM_RAW_PARTS,
69+
&paths::PTR_SLICE_FROM_RAW_PARTS_MUT,
70+
&paths::SLICE_FROM_RAW_PARTS,
71+
&paths::SLICE_FROM_RAW_PARTS_MUT,
6872
];
69-
const METHODS: [&str; 5] = [
70-
"write_bytes",
71-
"copy_to",
72-
"copy_from",
73-
"copy_to_nonoverlapping",
74-
"copy_from_nonoverlapping",
73+
const METHODS: [&str; 11] = [
74+
"write_bytes",
75+
"copy_to",
76+
"copy_from",
77+
"copy_to_nonoverlapping",
78+
"copy_from_nonoverlapping",
79+
"add",
80+
"wrapping_add",
81+
"sub",
82+
"wrapping_sub",
83+
"offset",
84+
"wrapping_offset",
7585
];
76-
fn get_pointee_ty_and_count_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<(Ty<'tcx>, &'tcx Expr<'tcx>)> {
86+
7787
if_chain! {
7888
// Find calls to ptr::{copy, copy_nonoverlapping}
7989
// and ptr::{swap_nonoverlapping, write_bytes},
@@ -92,12 +102,12 @@ fn get_pointee_ty_and_count_expr(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -
92102
if_chain! {
93103
// Find calls to copy_{from,to}{,_nonoverlapping} and write_bytes methods
94104
if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind;
95-
if let [ptr_self, _, count] = args;
105+
if let [ptr_self, .., count] = args;
96106
let method_ident = method_path.ident.as_str();
97107
if METHODS.iter().any(|m| *m == &*method_ident);
98108

99109
// Get the pointee type
100-
if let ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl:_mutability }) =
110+
if let ty::RawPtr(TypeAndMut { ty: pointee_ty, .. }) =
101111
cx.typeck_results().expr_ty(ptr_self).kind();
102112
then {
103113
return Some((pointee_ty, count));
@@ -115,7 +125,7 @@ impl<'tcx> LateLintPass<'tcx> for SizeOfInElementCount {
115125
instead of a count of elements of T";
116126

117127
if_chain! {
118-
// Find calls to unsafe copy functions and get
128+
// Find calls to functions with an element count parameter and get
119129
// the pointee type and count parameter expression
120130
if let Some((pointee_ty, count_expr)) = get_pointee_ty_and_count_expr(cx, expr);
121131

clippy_lints/src/utils/paths.rs

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ pub const RWLOCK_READ_GUARD: [&str; 4] = ["std", "sync", "rwlock", "RwLockReadGu
125125
pub const RWLOCK_WRITE_GUARD: [&str; 4] = ["std", "sync", "rwlock", "RwLockWriteGuard"];
126126
pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"];
127127
pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
128+
pub const SLICE_FROM_RAW_PARTS: [&str; 4] = ["core", "slice", "raw", "from_raw_parts"];
129+
pub const SLICE_FROM_RAW_PARTS_MUT: [&str; 4] = ["core", "slice", "raw", "from_raw_parts_mut"];
128130
pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
129131
pub const SLICE_ITER: [&str; 4] = ["core", "slice", "iter", "Iter"];
130132
pub const STDERR: [&str; 4] = ["std", "io", "stdio", "stderr"];

tests/ui/size_of_in_element_count.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
#![warn(clippy::size_of_in_element_count)]
2+
#![allow(clippy::ptr_offset_with_cast)]
23

34
use std::mem::{size_of, size_of_val};
45
use std::ptr::{
5-
copy, copy_nonoverlapping, slice_from_raw_parts,
6-
slice_from_raw_parts_mut, swap_nonoverlapping, write_bytes,
6+
copy, copy_nonoverlapping, slice_from_raw_parts, slice_from_raw_parts_mut, swap_nonoverlapping, write_bytes,
77
};
8+
use std::slice::{from_raw_parts, from_raw_parts_mut};
89

910
fn main() {
1011
const SIZE: usize = 128;
@@ -33,6 +34,16 @@ fn main() {
3334
slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE);
3435
slice_from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE);
3536

37+
unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE) };
38+
unsafe { from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE) };
39+
40+
unsafe { y.as_mut_ptr().sub(size_of::<u8>()) };
41+
y.as_ptr().wrapping_sub(size_of::<u8>());
42+
unsafe { y.as_ptr().add(size_of::<u8>()) };
43+
y.as_mut_ptr().wrapping_add(size_of::<u8>());
44+
unsafe { y.as_ptr().offset(size_of::<u8>() as isize) };
45+
y.as_mut_ptr().wrapping_offset(size_of::<u8>() as isize);
46+
3647
// Count expression involving multiplication of size_of (Should trigger the lint)
3748
unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };
3849

+81-17
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: found a count of bytes instead of a count of elements of T
2-
--> $DIR/size_of_in_element_count.rs:17:68
2+
--> $DIR/size_of_in_element_count.rs:18:68
33
|
44
LL | unsafe { copy_nonoverlapping::<u8>(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
55
| ^^^^^^^^^^^^^^^
@@ -8,124 +8,188 @@ LL | unsafe { copy_nonoverlapping::<u8>(x.as_ptr(), y.as_mut_ptr(), size_of:
88
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
99

1010
error: found a count of bytes instead of a count of elements of T
11-
--> $DIR/size_of_in_element_count.rs:18:62
11+
--> $DIR/size_of_in_element_count.rs:19:62
1212
|
1313
LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
1414
| ^^^^^^^^^^^^^^^^^^
1515
|
1616
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
1717

1818
error: found a count of bytes instead of a count of elements of T
19-
--> $DIR/size_of_in_element_count.rs:20:49
19+
--> $DIR/size_of_in_element_count.rs:21:49
2020
|
2121
LL | unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u8>()) };
2222
| ^^^^^^^^^^^^^^^
2323
|
2424
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
2525

2626
error: found a count of bytes instead of a count of elements of T
27-
--> $DIR/size_of_in_element_count.rs:21:64
27+
--> $DIR/size_of_in_element_count.rs:22:64
2828
|
2929
LL | unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u8>()) };
3030
| ^^^^^^^^^^^^^^^
3131
|
3232
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
3333

3434
error: found a count of bytes instead of a count of elements of T
35-
--> $DIR/size_of_in_element_count.rs:22:51
35+
--> $DIR/size_of_in_element_count.rs:23:51
3636
|
3737
LL | unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u8>()) };
3838
| ^^^^^^^^^^^^^^^
3939
|
4040
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
4141

4242
error: found a count of bytes instead of a count of elements of T
43-
--> $DIR/size_of_in_element_count.rs:23:66
43+
--> $DIR/size_of_in_element_count.rs:24:66
4444
|
4545
LL | unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u8>()) };
4646
| ^^^^^^^^^^^^^^^
4747
|
4848
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
4949

5050
error: found a count of bytes instead of a count of elements of T
51-
--> $DIR/size_of_in_element_count.rs:25:47
51+
--> $DIR/size_of_in_element_count.rs:26:47
5252
|
5353
LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
5454
| ^^^^^^^^^^^^^^^
5555
|
5656
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
5757

5858
error: found a count of bytes instead of a count of elements of T
59-
--> $DIR/size_of_in_element_count.rs:26:47
59+
--> $DIR/size_of_in_element_count.rs:27:47
6060
|
6161
LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
6262
| ^^^^^^^^^^^^^^^^^^
6363
|
6464
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
6565

6666
error: found a count of bytes instead of a count of elements of T
67-
--> $DIR/size_of_in_element_count.rs:28:46
67+
--> $DIR/size_of_in_element_count.rs:29:46
6868
|
6969
LL | unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::<u8>() * SIZE) };
7070
| ^^^^^^^^^^^^^^^^^^^^^^
7171
|
7272
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
7373

7474
error: found a count of bytes instead of a count of elements of T
75-
--> $DIR/size_of_in_element_count.rs:29:47
75+
--> $DIR/size_of_in_element_count.rs:30:47
7676
|
7777
LL | unsafe { write_bytes(y.as_mut_ptr(), 0u8, size_of::<u8>() * SIZE) };
7878
| ^^^^^^^^^^^^^^^^^^^^^^
7979
|
8080
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
8181

8282
error: found a count of bytes instead of a count of elements of T
83-
--> $DIR/size_of_in_element_count.rs:31:66
83+
--> $DIR/size_of_in_element_count.rs:32:66
8484
|
8585
LL | unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u8>() * SIZE) };
8686
| ^^^^^^^^^^^^^^^^^^^^^^
8787
|
8888
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
8989

9090
error: found a count of bytes instead of a count of elements of T
91-
--> $DIR/size_of_in_element_count.rs:33:46
91+
--> $DIR/size_of_in_element_count.rs:34:46
9292
|
9393
LL | slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE);
9494
| ^^^^^^^^^^^^^^^^^^^^^^
9595
|
9696
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
9797

9898
error: found a count of bytes instead of a count of elements of T
99-
--> $DIR/size_of_in_element_count.rs:34:38
99+
--> $DIR/size_of_in_element_count.rs:35:38
100100
|
101101
LL | slice_from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE);
102102
| ^^^^^^^^^^^^^^^^^^^^^^
103103
|
104104
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
105105

106106
error: found a count of bytes instead of a count of elements of T
107-
--> $DIR/size_of_in_element_count.rs:37:62
107+
--> $DIR/size_of_in_element_count.rs:37:49
108+
|
109+
LL | unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE) };
110+
| ^^^^^^^^^^^^^^^^^^^^^^
111+
|
112+
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
113+
114+
error: found a count of bytes instead of a count of elements of T
115+
--> $DIR/size_of_in_element_count.rs:38:41
116+
|
117+
LL | unsafe { from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE) };
118+
| ^^^^^^^^^^^^^^^^^^^^^^
119+
|
120+
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
121+
122+
error: found a count of bytes instead of a count of elements of T
123+
--> $DIR/size_of_in_element_count.rs:40:33
124+
|
125+
LL | unsafe { y.as_mut_ptr().sub(size_of::<u8>()) };
126+
| ^^^^^^^^^^^^^^^
127+
|
128+
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
129+
130+
error: found a count of bytes instead of a count of elements of T
131+
--> $DIR/size_of_in_element_count.rs:41:29
132+
|
133+
LL | y.as_ptr().wrapping_sub(size_of::<u8>());
134+
| ^^^^^^^^^^^^^^^
135+
|
136+
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
137+
138+
error: found a count of bytes instead of a count of elements of T
139+
--> $DIR/size_of_in_element_count.rs:42:29
140+
|
141+
LL | unsafe { y.as_ptr().add(size_of::<u8>()) };
142+
| ^^^^^^^^^^^^^^^
143+
|
144+
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
145+
146+
error: found a count of bytes instead of a count of elements of T
147+
--> $DIR/size_of_in_element_count.rs:43:33
148+
|
149+
LL | y.as_mut_ptr().wrapping_add(size_of::<u8>());
150+
| ^^^^^^^^^^^^^^^
151+
|
152+
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
153+
154+
error: found a count of bytes instead of a count of elements of T
155+
--> $DIR/size_of_in_element_count.rs:44:32
156+
|
157+
LL | unsafe { y.as_ptr().offset(size_of::<u8>() as isize) };
158+
| ^^^^^^^^^^^^^^^^^^^^^^^^
159+
|
160+
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
161+
162+
error: found a count of bytes instead of a count of elements of T
163+
--> $DIR/size_of_in_element_count.rs:45:36
164+
|
165+
LL | y.as_mut_ptr().wrapping_offset(size_of::<u8>() as isize);
166+
| ^^^^^^^^^^^^^^^^^^^^^^^^
167+
|
168+
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
169+
170+
error: found a count of bytes instead of a count of elements of T
171+
--> $DIR/size_of_in_element_count.rs:48:62
108172
|
109173
LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };
110174
| ^^^^^^^^^^^^^^^^^^^^^^
111175
|
112176
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
113177

114178
error: found a count of bytes instead of a count of elements of T
115-
--> $DIR/size_of_in_element_count.rs:40:62
179+
--> $DIR/size_of_in_element_count.rs:51:62
116180
|
117181
LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * size_of_val(&x[0]) * 2) };
118182
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
119183
|
120184
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
121185

122186
error: found a count of bytes instead of a count of elements of T
123-
--> $DIR/size_of_in_element_count.rs:43:47
187+
--> $DIR/size_of_in_element_count.rs:54:47
124188
|
125189
LL | unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u8>() / 2) };
126190
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
127191
|
128192
= help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
129193

130-
error: aborting due to 16 previous errors
194+
error: aborting due to 24 previous errors
131195

0 commit comments

Comments
 (0)