Skip to content

Commit

Permalink
Catch pointer::cast too in cast_ptr_alignment
Browse files Browse the repository at this point in the history
  • Loading branch information
rail-rain committed Jan 7, 2021
1 parent 8e5c5a6 commit f50ded0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 7 deletions.
35 changes: 29 additions & 6 deletions clippy_lints/src/types.rs
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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(
Expand Down
4 changes: 4 additions & 0 deletions tests/ui/cast_alignment.rs
Expand Up @@ -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::<u16>();
(&mut 1u8 as *mut u8).cast::<u16>();

/* These should be ok */

// not a pointer type
Expand Down
14 changes: 13 additions & 1 deletion tests/ui/cast_alignment.stderr
Expand Up @@ -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::<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

0 comments on commit f50ded0

Please sign in to comment.