diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 90f42eba1..69c37bb63 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -13,7 +13,7 @@ use syntax::ast::{FloatTy, IntTy, UintTy}; use syntax::codemap::Span; use syntax::errors::DiagnosticBuilder; use utils::{comparisons, higher, in_constant, in_external_macro, in_macro, last_path_segment, match_def_path, match_path, - multispan_sugg, opt_def_id, same_tys, snippet, snippet_opt, span_help_and_lint, span_lint, + match_type, multispan_sugg, opt_def_id, same_tys, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, clip, unsext, sext, int_bits}; use utils::paths; use consts::{constant, Constant}; @@ -981,6 +981,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass { if let Some(from_align) = cx.layout_of(from_ptr_ty.ty).ok().map(|a| a.align.abi()); if let Some(to_align) = cx.layout_of(to_ptr_ty.ty).ok().map(|a| a.align.abi()); if from_align < to_align; + // with c_void, we inherently need to trust the user + if ! ( + match_type(cx, from_ptr_ty.ty, &paths::C_VOID) + || match_type(cx, from_ptr_ty.ty, &paths::C_VOID_LIBC) + ); then { span_lint( cx, diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 8f823c12c..fbc3cc303 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -20,6 +20,8 @@ pub const CMP_MAX: [&str; 3] = ["core", "cmp", "max"]; pub const CMP_MIN: [&str; 3] = ["core", "cmp", "min"]; pub const COW: [&str; 3] = ["alloc", "borrow", "Cow"]; pub const CSTRING_NEW: [&str; 5] = ["std", "ffi", "c_str", "CString", "new"]; +pub const C_VOID: [&str; 4] = ["std", "os", "raw", "c_void"]; +pub const C_VOID_LIBC: [&str; 2] = ["libc", "c_void"]; pub const DEBUG_FMT_METHOD: [&str; 4] = ["core", "fmt", "Debug", "fmt"]; pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"]; pub const DISPLAY_FMT_METHOD: [&str; 4] = ["core", "fmt", "Display", "fmt"]; diff --git a/tests/ui/cast_alignment.rs b/tests/ui/cast_alignment.rs index 4985a90bd..32e2f9316 100644 --- a/tests/ui/cast_alignment.rs +++ b/tests/ui/cast_alignment.rs @@ -1,5 +1,9 @@ //! Test casts for alignment issues +#![feature(libc)] + +extern crate libc; + #[warn(cast_ptr_alignment)] #[allow(no_effect, unnecessary_operation, cast_lossless)] fn main() { @@ -16,4 +20,7 @@ fn main() { // cast to less-strictly-aligned type (&1u16 as *const u16) as *const u8; (&mut 1u16 as *mut u16) as *mut u8; + // For c_void, we should trust the user. See #2677 + (&1u32 as *const u32 as *const std::os::raw::c_void) as *const u32; + (&1u32 as *const u32 as *const libc::c_void) as *const u32; } diff --git a/tests/ui/cast_alignment.stderr b/tests/ui/cast_alignment.stderr index d9fffdd33..42df78a37 100644 --- a/tests/ui/cast_alignment.stderr +++ b/tests/ui/cast_alignment.stderr @@ -1,15 +1,15 @@ error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) - --> $DIR/cast_alignment.rs:9:5 - | -9 | (&1u8 as *const u8) as *const u16; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `-D cast-ptr-alignment` implied by `-D warnings` + --> $DIR/cast_alignment.rs:13:5 + | +13 | (&1u8 as *const u8) as *const u16; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D cast-ptr-alignment` implied by `-D warnings` error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) - --> $DIR/cast_alignment.rs:10:5 + --> $DIR/cast_alignment.rs:14:5 | -10 | (&mut 1u8 as *mut u8) as *mut u16; +14 | (&mut 1u8 as *mut u8) as *mut u16; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors