mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-27 09:14:20 +00:00
Fix c_void false positive caused by libc refactoring
The path of `libc::c_void` has changes in 5c1a6b8a6d
The DefId path is now always platform specific like
`libc::windows::c_void`. This fixes our c_void detection to only check
the first and last elements.
This commit is contained in:
parent
f13d23de41
commit
d90cad24a1
@ -28,8 +28,9 @@ use crate::syntax::source_map::Span;
|
||||
use crate::utils::paths;
|
||||
use crate::utils::{
|
||||
clip, comparisons, differing_macro_contexts, higher, in_constant, in_macro, int_bits, last_path_segment,
|
||||
match_def_path, match_path, match_type, multispan_sugg, opt_def_id, same_tys, sext, snippet, snippet_opt,
|
||||
match_def_path, match_path, multispan_sugg, opt_def_id, same_tys, sext, snippet, snippet_opt,
|
||||
snippet_with_applicability, span_help_and_lint, span_lint, span_lint_and_sugg, span_lint_and_then, unsext,
|
||||
AbsolutePathBuffer
|
||||
};
|
||||
use if_chain::if_chain;
|
||||
use std::borrow::Cow;
|
||||
@ -1023,6 +1024,21 @@ impl LintPass for CastPass {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the given type is either `core::ffi::c_void` or
|
||||
// one of the platform specific `libc::<platform>::c_void` of libc.
|
||||
fn is_c_void(tcx: TyCtxt<'_, '_, '_>, ty: Ty<'_>) -> bool {
|
||||
if let ty::Adt(adt, _) = ty.sty {
|
||||
let mut apb = AbsolutePathBuffer { names: vec![] };
|
||||
tcx.push_item_path(&mut apb, adt.did, false);
|
||||
|
||||
if apb.names.is_empty() { return false }
|
||||
if apb.names[0] == "libc" || apb.names[0] == "core" && *apb.names.last().unwrap() == "c_void" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass {
|
||||
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
|
||||
if let ExprKind::Cast(ref ex, _) = expr.node {
|
||||
@ -1114,10 +1130,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CastPass {
|
||||
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)
|
||||
);
|
||||
if !is_c_void(cx.tcx, from_ptr_ty.ty);
|
||||
then {
|
||||
span_lint(
|
||||
cx,
|
||||
|
@ -29,6 +29,7 @@ use crate::syntax::attr;
|
||||
use crate::syntax::errors::DiagnosticBuilder;
|
||||
use crate::syntax::source_map::{Span, DUMMY_SP};
|
||||
use crate::syntax::symbol::{keywords, Symbol};
|
||||
use crate::syntax::symbol;
|
||||
use if_chain::if_chain;
|
||||
use matches::matches;
|
||||
use std::borrow::Cow;
|
||||
@ -74,6 +75,25 @@ pub fn in_macro(span: Span) -> bool {
|
||||
span.ctxt().outer().expn_info().is_some()
|
||||
}
|
||||
|
||||
/// Used to store the absolute path to a type.
|
||||
///
|
||||
/// See `match_def_path` for usage.
|
||||
#[derive(Debug)]
|
||||
pub struct AbsolutePathBuffer {
|
||||
pub names: Vec<symbol::LocalInternedString>,
|
||||
}
|
||||
|
||||
impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
|
||||
fn root_mode(&self) -> &ty::item_path::RootMode {
|
||||
const ABSOLUTE: &ty::item_path::RootMode = &ty::item_path::RootMode::Absolute;
|
||||
ABSOLUTE
|
||||
}
|
||||
|
||||
fn push(&mut self, text: &str) {
|
||||
self.names.push(symbol::Symbol::intern(text).as_str());
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if a `DefId`'s path matches the given absolute type path usage.
|
||||
///
|
||||
/// # Examples
|
||||
@ -83,24 +103,6 @@ pub fn in_macro(span: Span) -> bool {
|
||||
///
|
||||
/// See also the `paths` module.
|
||||
pub fn match_def_path(tcx: TyCtxt<'_, '_, '_>, def_id: DefId, path: &[&str]) -> bool {
|
||||
use crate::syntax::symbol;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct AbsolutePathBuffer {
|
||||
names: Vec<symbol::LocalInternedString>,
|
||||
}
|
||||
|
||||
impl ty::item_path::ItemPathBuffer for AbsolutePathBuffer {
|
||||
fn root_mode(&self) -> &ty::item_path::RootMode {
|
||||
const ABSOLUTE: &ty::item_path::RootMode = &ty::item_path::RootMode::Absolute;
|
||||
ABSOLUTE
|
||||
}
|
||||
|
||||
fn push(&mut self, text: &str) {
|
||||
self.names.push(symbol::Symbol::intern(text).as_str());
|
||||
}
|
||||
}
|
||||
|
||||
let mut apb = AbsolutePathBuffer { names: vec![] };
|
||||
|
||||
tcx.push_item_path(&mut apb, def_id, false);
|
||||
|
@ -27,8 +27,6 @@ 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; 3] = ["core", "ffi", "c_void"];
|
||||
pub const C_VOID_LIBC: [&str; 2] = ["libc", "c_void"];
|
||||
pub const DEFAULT_TRAIT: [&str; 3] = ["core", "default", "Default"];
|
||||
pub const DEFAULT_TRAIT_METHOD: [&str; 4] = ["core", "default", "Default", "default"];
|
||||
pub const DEREF_TRAIT_METHOD: [&str; 5] = ["core", "ops", "deref", "Deref", "deref"];
|
||||
|
Loading…
Reference in New Issue
Block a user