Skip to content

Commit d15c9c1

Browse files
committed
Auto merge of #4816 - rust-lang:zst-offset, r=phansch
New lint: zst_offset This fixes #4813 changelog: add `zst_offset` lint
2 parents 60e8413 + c21b198 commit d15c9c1

File tree

7 files changed

+67
-2
lines changed

7 files changed

+67
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1273,4 +1273,5 @@ Released 2018-09-13
12731273
[`zero_prefixed_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_prefixed_literal
12741274
[`zero_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr
12751275
[`zero_width_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_width_space
1276+
[`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
12761277
<!-- end autogenerated links to lint list -->

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
88

9-
[There are 333 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
9+
[There are 334 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
1010

1111
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
1212

clippy_lints/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
624624
&methods::USELESS_ASREF,
625625
&methods::WRONG_PUB_SELF_CONVENTION,
626626
&methods::WRONG_SELF_CONVENTION,
627+
&methods::ZST_OFFSET,
627628
&minmax::MIN_MAX,
628629
&misc::CMP_NAN,
629630
&misc::CMP_OWNED,
@@ -1176,6 +1177,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
11761177
LintId::of(&methods::UNNECESSARY_FOLD),
11771178
LintId::of(&methods::USELESS_ASREF),
11781179
LintId::of(&methods::WRONG_SELF_CONVENTION),
1180+
LintId::of(&methods::ZST_OFFSET),
11791181
LintId::of(&minmax::MIN_MAX),
11801182
LintId::of(&misc::CMP_NAN),
11811183
LintId::of(&misc::CMP_OWNED),
@@ -1497,6 +1499,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
14971499
LintId::of(&methods::CLONE_DOUBLE_REF),
14981500
LintId::of(&methods::TEMPORARY_CSTRING_AS_PTR),
14991501
LintId::of(&methods::UNINIT_ASSUMED_INIT),
1502+
LintId::of(&methods::ZST_OFFSET),
15001503
LintId::of(&minmax::MIN_MAX),
15011504
LintId::of(&misc::CMP_NAN),
15021505
LintId::of(&misc::FLOAT_CMP),

clippy_lints/src/methods/mod.rs

+33
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,23 @@ declare_clippy_lint! {
10651065
"`.chcked_add/sub(x).unwrap_or(MAX/MIN)`"
10661066
}
10671067

1068+
declare_clippy_lint! {
1069+
/// **What it does:** Checks for `offset(_)`, `wrapping_`{`add`, `sub`}, etc. on raw pointers to
1070+
/// zero-sized types
1071+
///
1072+
/// **Why is this bad?** This is a no-op, and likely unintended
1073+
///
1074+
/// **Known problems:** None
1075+
///
1076+
/// **Example:**
1077+
/// ```ignore
1078+
/// unsafe { (&() as *const ()).offest(1) };
1079+
/// ```
1080+
pub ZST_OFFSET,
1081+
correctness,
1082+
"Check for offset calculations on raw pointers to zero-sized types"
1083+
}
1084+
10681085
declare_lint_pass!(Methods => [
10691086
OPTION_UNWRAP_USED,
10701087
RESULT_UNWRAP_USED,
@@ -1109,6 +1126,7 @@ declare_lint_pass!(Methods => [
11091126
SUSPICIOUS_MAP,
11101127
UNINIT_ASSUMED_INIT,
11111128
MANUAL_SATURATING_ARITHMETIC,
1129+
ZST_OFFSET,
11121130
]);
11131131

11141132
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
@@ -1167,6 +1185,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
11671185
| ["unwrap_or", arith @ "checked_mul"] => {
11681186
manual_saturating_arithmetic::lint(cx, expr, &arg_lists, &arith["checked_".len()..])
11691187
},
1188+
["add"] | ["offset"] | ["sub"] | ["wrapping_offset"] | ["wrapping_add"] | ["wrapping_sub"] => {
1189+
check_pointer_offset(cx, expr, arg_lists[0])
1190+
},
11701191
_ => {},
11711192
}
11721193

@@ -3063,3 +3084,15 @@ fn contains_return(expr: &hir::Expr) -> bool {
30633084
visitor.visit_expr(expr);
30643085
visitor.found
30653086
}
3087+
3088+
fn check_pointer_offset(cx: &LateContext<'_, '_>, expr: &hir::Expr, args: &[hir::Expr]) {
3089+
if_chain! {
3090+
if args.len() == 2;
3091+
if let ty::RawPtr(ty::TypeAndMut { ref ty, .. }) = cx.tables.expr_ty(&args[0]).kind;
3092+
if let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(ty));
3093+
if layout.is_zst();
3094+
then {
3095+
span_lint(cx, ZST_OFFSET, expr.span, "offset calculation on zero-sized value");
3096+
}
3097+
}
3098+
}

src/lintlist/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub use lint::Lint;
66
pub use lint::LINT_LEVELS;
77

88
// begin lint list, do not remove this comment, it’s used in `update_lints`
9-
pub const ALL_LINTS: [Lint; 333] = [
9+
pub const ALL_LINTS: [Lint; 334] = [
1010
Lint {
1111
name: "absurd_extreme_comparisons",
1212
group: "correctness",
@@ -2338,5 +2338,12 @@ pub const ALL_LINTS: [Lint; 333] = [
23382338
deprecation: None,
23392339
module: "unicode",
23402340
},
2341+
Lint {
2342+
name: "zst_offset",
2343+
group: "correctness",
2344+
desc: "Check for offset calculations on raw pointers to zero-sized types",
2345+
deprecation: None,
2346+
module: "methods",
2347+
},
23412348
];
23422349
// end lint list, do not remove this comment, it’s used in `update_lints`

tests/ui/zero_offset.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
fn main() {
2+
unsafe {
3+
let x = &() as *const ();
4+
x.offset(0);
5+
x.wrapping_add(0);
6+
x.sub(0);
7+
x.wrapping_sub(0);
8+
9+
let y = &1 as *const u8;
10+
y.offset(0);
11+
}
12+
}

tests/ui/zero_offset.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0606]: casting `&i32` as `*const u8` is invalid
2+
--> $DIR/zero_offset.rs:9:17
3+
|
4+
LL | let y = &1 as *const u8;
5+
| ^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0606`.

0 commit comments

Comments
 (0)