Catch pointer::cast too in cast_ptr_alignment

This commit is contained in:
rail 2021-01-07 16:41:15 +13:00
parent 8e5c5a64a5
commit f50ded0592
3 changed files with 46 additions and 7 deletions

View file

@ -1637,12 +1637,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
return; return;
} }
if let ExprKind::Cast(ref ex, cast_to) = expr.kind { if let ExprKind::Cast(ref ex, cast_to) = expr.kind {
if let TyKind::Path(QPath::Resolved(_, path)) = cast_to.kind { if is_hir_ty_cfg_dependant(cx, cast_to) {
if let Res::Def(_, def_id) = path.res { return;
if cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr) {
return;
}
}
} }
let (cast_from, cast_to) = (cx.typeck_results().expr_ty(ex), cx.typeck_results().expr_ty(expr)); let (cast_from, cast_to) = (cx.typeck_results().expr_ty(ex), cx.typeck_results().expr_ty(expr));
lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to); lint_fn_to_numeric_cast(cx, expr, ex, cast_from, cast_to);
@ -1691,6 +1687,21 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
lint_numeric_casts(cx, expr, ex, cast_from, cast_to); lint_numeric_casts(cx, expr, ex, cast_from, cast_to);
} }
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
} else if let ExprKind::MethodCall(method_path, _, args, _) = expr.kind {
if method_path.ident.name != sym!(cast) {
return;
}
if_chain! {
if let Some(generic_args) = method_path.args;
if let [GenericArg::Type(cast_to)] = generic_args.args;
// There probably is no obvious reason to do this, just to be consistent with `as` cases.
if is_hir_ty_cfg_dependant(cx, cast_to);
then {
return;
}
}
let (cast_from, cast_to) = (cx.typeck_results().expr_ty(&args[0]), cx.typeck_results().expr_ty(expr));
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
} }
} }
@ -1714,6 +1725,18 @@ fn get_numeric_literal<'e>(expr: &'e Expr<'e>) -> Option<&'e Lit> {
} }
} }
fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
if_chain! {
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind;
if let Res::Def(_, def_id) = path.res;
then {
cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr)
} else {
false
}
}
}
fn show_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) { fn show_unnecessary_cast(cx: &LateContext<'_>, expr: &Expr<'_>, literal_str: &str, cast_from: Ty<'_>, cast_to: Ty<'_>) {
let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" }; let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" };
span_lint_and_sugg( span_lint_and_sugg(

View file

@ -12,6 +12,10 @@ fn main() {
(&1u8 as *const u8) as *const u16; (&1u8 as *const u8) as *const u16;
(&mut 1u8 as *mut u8) as *mut u16; (&mut 1u8 as *mut u8) as *mut u16;
// cast to more-strictly-aligned type, but with the `pointer::cast` function.
(&1u8 as *const u8).cast::<u16>();
(&mut 1u8 as *mut u8).cast::<u16>();
/* These should be ok */ /* These should be ok */
// not a pointer type // not a pointer type

View file

@ -12,5 +12,17 @@ error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1
LL | (&mut 1u8 as *mut u8) as *mut u16; LL | (&mut 1u8 as *mut u8) as *mut u16;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
--> $DIR/cast_alignment.rs:15:5
|
LL | (&1u8 as *const u8).cast::<u16>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
--> $DIR/cast_alignment.rs:16:5
|
LL | (&mut 1u8 as *mut u8).cast::<u16>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors