From f50ded059272ed3c060ea5df353966384d7df427 Mon Sep 17 00:00:00 2001 From: rail <12975677+rail-rain@users.noreply.github.com> Date: Thu, 7 Jan 2021 16:41:15 +1300 Subject: [PATCH] Catch `pointer::cast` too in `cast_ptr_alignment` --- clippy_lints/src/types.rs | 35 ++++++++++++++++++++++++++++------ tests/ui/cast_alignment.rs | 4 ++++ tests/ui/cast_alignment.stderr | 14 +++++++++++++- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index b21f81bd517..2d256b38b0d 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -1637,12 +1637,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts { return; } if let ExprKind::Cast(ref ex, cast_to) = expr.kind { - if let TyKind::Path(QPath::Resolved(_, path)) = cast_to.kind { - if let Res::Def(_, def_id) = path.res { - if cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr) { - return; - } - } + if is_hir_ty_cfg_dependant(cx, cast_to) { + return; } 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); @@ -1691,6 +1687,21 @@ impl<'tcx> LateLintPass<'tcx> for Casts { 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); } } @@ -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<'_>) { let literal_kind_name = if cast_from.is_integral() { "integer" } else { "float" }; span_lint_and_sugg( diff --git a/tests/ui/cast_alignment.rs b/tests/ui/cast_alignment.rs index 4c08935639f..d011e84b115 100644 --- a/tests/ui/cast_alignment.rs +++ b/tests/ui/cast_alignment.rs @@ -12,6 +12,10 @@ fn main() { (&1u8 as *const u8) as *const 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::(); + (&mut 1u8 as *mut u8).cast::(); + /* These should be ok */ // not a pointer type diff --git a/tests/ui/cast_alignment.stderr b/tests/ui/cast_alignment.stderr index 79219f86155..97e31c130a9 100644 --- a/tests/ui/cast_alignment.stderr +++ b/tests/ui/cast_alignment.stderr @@ -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; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -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::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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::(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors