@@ -1261,3 +1261,54 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields {
1261
1261
}
1262
1262
}
1263
1263
}
1264
+
1265
+
1266
+ /// Lint for casts from types other than `usize` or `isize` to raw pointers
1267
+ pub struct IntoToRawPtrCast ;
1268
+
1269
+ declare_lint ! {
1270
+ pub INT_TO_RAW_PTR_CAST ,
1271
+ Deny ,
1272
+ "cast from signed int other than `isize` to raw pointer"
1273
+ }
1274
+
1275
+ impl LintPass for IntoToRawPtrCast {
1276
+ fn get_lints ( & self ) -> LintArray {
1277
+ lint_array ! ( INT_TO_RAW_PTR_CAST )
1278
+ }
1279
+ }
1280
+
1281
+ impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for IntoToRawPtrCast {
1282
+ fn check_expr ( & mut self , cx : & LateContext , expr : & hir:: Expr ) {
1283
+ if let hir:: ExprCast ( ref base, _) = expr. node {
1284
+ let base_ty = cx. tables . expr_ty ( base) ;
1285
+ let target_ty = cx. tables . expr_ty ( expr) ;
1286
+ if let ty:: TyRawPtr ( ..) = target_ty. sty {
1287
+ match base_ty. sty {
1288
+ ty:: TyInt ( ast:: IntTy :: Is ) |
1289
+ ty:: TyInt ( ast:: IntTy :: I128 ) |
1290
+ ty:: TyInt ( ast:: IntTy :: I64 ) => return ,
1291
+ ty:: TyInt ( ast:: IntTy :: I32 ) => {
1292
+ if cx. tcx . data_layout . pointer_size . bytes ( ) <= 4 {
1293
+ return ;
1294
+ }
1295
+ } ,
1296
+ ty:: TyInt ( ast:: IntTy :: I16 ) => {
1297
+ if cx. tcx . data_layout . pointer_size . bytes ( ) <= 2 {
1298
+ return ;
1299
+ }
1300
+ } ,
1301
+ // these we report
1302
+ ty:: TyInt ( _) => { } ,
1303
+ // only int casts are relevant
1304
+ _ => return ,
1305
+ }
1306
+ cx. span_lint (
1307
+ INT_TO_RAW_PTR_CAST ,
1308
+ expr. span ,
1309
+ & format ! ( "cast from `{}` to raw pointer" , base_ty) ,
1310
+ ) ;
1311
+ }
1312
+ }
1313
+ }
1314
+ }
0 commit comments