@@ -1065,6 +1065,23 @@ declare_clippy_lint! {
1065
1065
"`.chcked_add/sub(x).unwrap_or(MAX/MIN)`"
1066
1066
}
1067
1067
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
+
1068
1085
declare_lint_pass ! ( Methods => [
1069
1086
OPTION_UNWRAP_USED ,
1070
1087
RESULT_UNWRAP_USED ,
@@ -1109,6 +1126,7 @@ declare_lint_pass!(Methods => [
1109
1126
SUSPICIOUS_MAP ,
1110
1127
UNINIT_ASSUMED_INIT ,
1111
1128
MANUAL_SATURATING_ARITHMETIC ,
1129
+ ZST_OFFSET ,
1112
1130
] ) ;
1113
1131
1114
1132
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for Methods {
@@ -1167,6 +1185,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
1167
1185
| [ "unwrap_or" , arith @ "checked_mul" ] => {
1168
1186
manual_saturating_arithmetic:: lint ( cx, expr, & arg_lists, & arith[ "checked_" . len ( ) ..] )
1169
1187
} ,
1188
+ [ "add" ] | [ "offset" ] | [ "sub" ] | [ "wrapping_offset" ] | [ "wrapping_add" ] | [ "wrapping_sub" ] => {
1189
+ check_pointer_offset ( cx, expr, arg_lists[ 0 ] )
1190
+ } ,
1170
1191
_ => { } ,
1171
1192
}
1172
1193
@@ -3063,3 +3084,15 @@ fn contains_return(expr: &hir::Expr) -> bool {
3063
3084
visitor. visit_expr ( expr) ;
3064
3085
visitor. found
3065
3086
}
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
+ }
0 commit comments