mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-31 22:41:50 +00:00
lint on unnecessary and plain wrong transmutes
This commit is contained in:
parent
5aea20da7f
commit
e06bc37477
@ -1,6 +1,9 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## 0.0.78 - TBA
|
||||||
|
* New lints: [`wrong_transmute`]
|
||||||
|
|
||||||
## 0.0.77 — 2016-06-21
|
## 0.0.77 — 2016-06-21
|
||||||
* Rustup to *rustc 1.11.0-nightly (5522e678b 2016-06-20)*
|
* Rustup to *rustc 1.11.0-nightly (5522e678b 2016-06-20)*
|
||||||
* New lints: [`stutter`] and [`iter_nth`]
|
* New lints: [`stutter`] and [`iter_nth`]
|
||||||
@ -276,6 +279,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
[`while_let_on_iterator`]: https://github.com/Manishearth/rust-clippy/wiki#while_let_on_iterator
|
[`while_let_on_iterator`]: https://github.com/Manishearth/rust-clippy/wiki#while_let_on_iterator
|
||||||
[`wrong_pub_self_convention`]: https://github.com/Manishearth/rust-clippy/wiki#wrong_pub_self_convention
|
[`wrong_pub_self_convention`]: https://github.com/Manishearth/rust-clippy/wiki#wrong_pub_self_convention
|
||||||
[`wrong_self_convention`]: https://github.com/Manishearth/rust-clippy/wiki#wrong_self_convention
|
[`wrong_self_convention`]: https://github.com/Manishearth/rust-clippy/wiki#wrong_self_convention
|
||||||
|
[`wrong_transmute`]: https://github.com/Manishearth/rust-clippy/wiki#wrong_transmute
|
||||||
[`zero_divided_by_zero`]: https://github.com/Manishearth/rust-clippy/wiki#zero_divided_by_zero
|
[`zero_divided_by_zero`]: https://github.com/Manishearth/rust-clippy/wiki#zero_divided_by_zero
|
||||||
[`zero_width_space`]: https://github.com/Manishearth/rust-clippy/wiki#zero_width_space
|
[`zero_width_space`]: https://github.com/Manishearth/rust-clippy/wiki#zero_width_space
|
||||||
<!-- end autogenerated links to wiki -->
|
<!-- end autogenerated links to wiki -->
|
||||||
|
@ -17,7 +17,7 @@ Table of contents:
|
|||||||
|
|
||||||
## Lints
|
## Lints
|
||||||
|
|
||||||
There are 155 lints included in this crate:
|
There are 156 lints included in this crate:
|
||||||
|
|
||||||
name | default | meaning
|
name | default | meaning
|
||||||
---------------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -168,12 +168,13 @@ name
|
|||||||
[used_underscore_binding](https://github.com/Manishearth/rust-clippy/wiki#used_underscore_binding) | allow | using a binding which is prefixed with an underscore
|
[used_underscore_binding](https://github.com/Manishearth/rust-clippy/wiki#used_underscore_binding) | allow | using a binding which is prefixed with an underscore
|
||||||
[useless_format](https://github.com/Manishearth/rust-clippy/wiki#useless_format) | warn | useless use of `format!`
|
[useless_format](https://github.com/Manishearth/rust-clippy/wiki#useless_format) | warn | useless use of `format!`
|
||||||
[useless_let_if_seq](https://github.com/Manishearth/rust-clippy/wiki#useless_let_if_seq) | warn | Checks for unidiomatic `let mut` declaration followed by initialization in `if`
|
[useless_let_if_seq](https://github.com/Manishearth/rust-clippy/wiki#useless_let_if_seq) | warn | Checks for unidiomatic `let mut` declaration followed by initialization in `if`
|
||||||
[useless_transmute](https://github.com/Manishearth/rust-clippy/wiki#useless_transmute) | warn | transmutes that have the same to and from types
|
[useless_transmute](https://github.com/Manishearth/rust-clippy/wiki#useless_transmute) | warn | transmutes that have the same to and from types or could be a cast/coercion
|
||||||
[useless_vec](https://github.com/Manishearth/rust-clippy/wiki#useless_vec) | warn | useless `vec!`
|
[useless_vec](https://github.com/Manishearth/rust-clippy/wiki#useless_vec) | warn | useless `vec!`
|
||||||
[while_let_loop](https://github.com/Manishearth/rust-clippy/wiki#while_let_loop) | warn | `loop { if let { ... } else break }` can be written as a `while let` loop
|
[while_let_loop](https://github.com/Manishearth/rust-clippy/wiki#while_let_loop) | warn | `loop { if let { ... } else break }` can be written as a `while let` loop
|
||||||
[while_let_on_iterator](https://github.com/Manishearth/rust-clippy/wiki#while_let_on_iterator) | warn | using a while-let loop instead of a for loop on an iterator
|
[while_let_on_iterator](https://github.com/Manishearth/rust-clippy/wiki#while_let_on_iterator) | warn | using a while-let loop instead of a for loop on an iterator
|
||||||
[wrong_pub_self_convention](https://github.com/Manishearth/rust-clippy/wiki#wrong_pub_self_convention) | allow | defining a public method named with an established prefix (like "into_") that takes `self` with the wrong convention
|
[wrong_pub_self_convention](https://github.com/Manishearth/rust-clippy/wiki#wrong_pub_self_convention) | allow | defining a public method named with an established prefix (like "into_") that takes `self` with the wrong convention
|
||||||
[wrong_self_convention](https://github.com/Manishearth/rust-clippy/wiki#wrong_self_convention) | warn | defining a method named with an established prefix (like "into_") that takes `self` with the wrong convention
|
[wrong_self_convention](https://github.com/Manishearth/rust-clippy/wiki#wrong_self_convention) | warn | defining a method named with an established prefix (like "into_") that takes `self` with the wrong convention
|
||||||
|
[wrong_transmute](https://github.com/Manishearth/rust-clippy/wiki#wrong_transmute) | warn | transmutes that are confusing at best, undefined behaviour at worst and always useless
|
||||||
[zero_divided_by_zero](https://github.com/Manishearth/rust-clippy/wiki#zero_divided_by_zero) | warn | usage of `0.0 / 0.0` to obtain NaN instead of std::f32::NaN or std::f64::NaN
|
[zero_divided_by_zero](https://github.com/Manishearth/rust-clippy/wiki#zero_divided_by_zero) | warn | usage of `0.0 / 0.0` to obtain NaN instead of std::f32::NaN or std::f64::NaN
|
||||||
[zero_width_space](https://github.com/Manishearth/rust-clippy/wiki#zero_width_space) | deny | using a zero-width space in a string literal, which is confusing
|
[zero_width_space](https://github.com/Manishearth/rust-clippy/wiki#zero_width_space) | deny | using a zero-width space in a string literal, which is confusing
|
||||||
|
|
||||||
|
@ -403,6 +403,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
|||||||
transmute::CROSSPOINTER_TRANSMUTE,
|
transmute::CROSSPOINTER_TRANSMUTE,
|
||||||
transmute::TRANSMUTE_PTR_TO_REF,
|
transmute::TRANSMUTE_PTR_TO_REF,
|
||||||
transmute::USELESS_TRANSMUTE,
|
transmute::USELESS_TRANSMUTE,
|
||||||
|
transmute::WRONG_TRANSMUTE,
|
||||||
types::ABSURD_EXTREME_COMPARISONS,
|
types::ABSURD_EXTREME_COMPARISONS,
|
||||||
types::BOX_VEC,
|
types::BOX_VEC,
|
||||||
types::CHAR_LIT_AS_U8,
|
types::CHAR_LIT_AS_U8,
|
||||||
|
@ -1,11 +1,25 @@
|
|||||||
use rustc::lint::*;
|
use rustc::lint::*;
|
||||||
use rustc::ty::TypeVariants::{TyRawPtr, TyRef};
|
use rustc::ty::TypeVariants::{TyRawPtr, TyRef};
|
||||||
|
use rustc::ty;
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
use utils::{match_def_path, paths, snippet_opt, span_lint, span_lint_and_then};
|
use utils::{match_def_path, paths, snippet_opt, span_lint, span_lint_and_then};
|
||||||
|
|
||||||
/// **What it does:** This lint checks for transmutes to the original type of the object.
|
/// **What it does:** This lint checks for transmutes that can't ever be correct on any architecture
|
||||||
///
|
///
|
||||||
/// **Why is this bad?** Readability. The code tricks people into thinking that the original value was of some other type.
|
/// **Why is this bad?** It's basically guaranteed to be undefined behaviour
|
||||||
|
///
|
||||||
|
/// **Known problems:** When accessing C, users might want to store pointer sized objects in `extradata` arguments to save an allocation.
|
||||||
|
///
|
||||||
|
/// **Example:** `let ptr: *const T = core::intrinsics::transmute('x')`.
|
||||||
|
declare_lint! {
|
||||||
|
pub WRONG_TRANSMUTE,
|
||||||
|
Warn,
|
||||||
|
"transmutes that are confusing at best, undefined behaviour at worst and always useless"
|
||||||
|
}
|
||||||
|
|
||||||
|
/// **What it does:** This lint checks for transmutes to the original type of the object and transmutes that could be a cast.
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** Readability. The code tricks people into thinking that something complex is going on
|
||||||
///
|
///
|
||||||
/// **Known problems:** None.
|
/// **Known problems:** None.
|
||||||
///
|
///
|
||||||
@ -13,7 +27,7 @@ use utils::{match_def_path, paths, snippet_opt, span_lint, span_lint_and_then};
|
|||||||
declare_lint! {
|
declare_lint! {
|
||||||
pub USELESS_TRANSMUTE,
|
pub USELESS_TRANSMUTE,
|
||||||
Warn,
|
Warn,
|
||||||
"transmutes that have the same to and from types"
|
"transmutes that have the same to and from types or could be a cast/coercion"
|
||||||
}
|
}
|
||||||
|
|
||||||
/// **What it does:*** This lint checks for transmutes between a type `T` and `*T`.
|
/// **What it does:*** This lint checks for transmutes between a type `T` and `*T`.
|
||||||
@ -51,7 +65,7 @@ pub struct Transmute;
|
|||||||
|
|
||||||
impl LintPass for Transmute {
|
impl LintPass for Transmute {
|
||||||
fn get_lints(&self) -> LintArray {
|
fn get_lints(&self) -> LintArray {
|
||||||
lint_array![CROSSPOINTER_TRANSMUTE, TRANSMUTE_PTR_TO_REF, USELESS_TRANSMUTE]
|
lint_array![CROSSPOINTER_TRANSMUTE, TRANSMUTE_PTR_TO_REF, USELESS_TRANSMUTE, WRONG_TRANSMUTE]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,6 +103,27 @@ impl LateLintPass for Transmute {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
(&ty::TyInt(_), &TyRawPtr(_)) |
|
||||||
|
(&ty::TyUint(_), &TyRawPtr(_)) => span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
USELESS_TRANSMUTE,
|
||||||
|
e.span,
|
||||||
|
"transmute from an integer to a pointer",
|
||||||
|
|db| {
|
||||||
|
if let Some(arg) = snippet_opt(cx, args[0].span) {
|
||||||
|
db.span_suggestion(e.span, "try", format!("{} as {}", arg, to_ty));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(&ty::TyFloat(_), &TyRef(..)) |
|
||||||
|
(&ty::TyFloat(_), &TyRawPtr(_)) |
|
||||||
|
(&ty::TyChar, &TyRef(..)) |
|
||||||
|
(&ty::TyChar, &TyRawPtr(_)) => span_lint(
|
||||||
|
cx,
|
||||||
|
WRONG_TRANSMUTE,
|
||||||
|
e.span,
|
||||||
|
&format!("transmute from a `{}` to a pointer", from_ty),
|
||||||
|
),
|
||||||
(&TyRawPtr(from_ptr), _) if from_ptr.ty == to_ty => span_lint(
|
(&TyRawPtr(from_ptr), _) if from_ptr.ty == to_ty => span_lint(
|
||||||
cx,
|
cx,
|
||||||
CROSSPOINTER_TRANSMUTE,
|
CROSSPOINTER_TRANSMUTE,
|
||||||
|
@ -6,8 +6,8 @@ extern crate core;
|
|||||||
use std::mem::transmute as my_transmute;
|
use std::mem::transmute as my_transmute;
|
||||||
use std::vec::Vec as MyVec;
|
use std::vec::Vec as MyVec;
|
||||||
|
|
||||||
fn my_int() -> usize {
|
fn my_int() -> Usize {
|
||||||
42
|
Usize(42)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn my_vec() -> MyVec<i32> {
|
fn my_vec() -> MyVec<i32> {
|
||||||
@ -100,27 +100,34 @@ fn useless() {
|
|||||||
let _: Vec<u32> = std::intrinsics::transmute(my_vec());
|
let _: Vec<u32> = std::intrinsics::transmute(my_vec());
|
||||||
let _: Vec<u32> = std::mem::transmute(my_vec());
|
let _: Vec<u32> = std::mem::transmute(my_vec());
|
||||||
let _: Vec<u32> = my_transmute(my_vec());
|
let _: Vec<u32> = my_transmute(my_vec());
|
||||||
|
|
||||||
|
let _: *const usize = std::mem::transmute(5_isize);
|
||||||
|
//~^ ERROR transmute from an integer to a pointer
|
||||||
|
//~| HELP try
|
||||||
|
//~| SUGGESTION 5_isize as *const usize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Usize(usize);
|
||||||
|
|
||||||
#[deny(crosspointer_transmute)]
|
#[deny(crosspointer_transmute)]
|
||||||
fn crosspointer() {
|
fn crosspointer() {
|
||||||
let mut int: usize = 0;
|
let mut int: Usize = Usize(0);
|
||||||
let int_const_ptr: *const usize = &int as *const usize;
|
let int_const_ptr: *const Usize = &int as *const Usize;
|
||||||
let int_mut_ptr: *mut usize = &mut int as *mut usize;
|
let int_mut_ptr: *mut Usize = &mut int as *mut Usize;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let _: usize = core::intrinsics::transmute(int_const_ptr);
|
let _: Usize = core::intrinsics::transmute(int_const_ptr);
|
||||||
//~^ ERROR transmute from a type (`*const usize`) to the type that it points to (`usize`)
|
//~^ ERROR transmute from a type (`*const Usize`) to the type that it points to (`Usize`)
|
||||||
|
|
||||||
let _: usize = core::intrinsics::transmute(int_mut_ptr);
|
let _: Usize = core::intrinsics::transmute(int_mut_ptr);
|
||||||
//~^ ERROR transmute from a type (`*mut usize`) to the type that it points to (`usize`)
|
//~^ ERROR transmute from a type (`*mut Usize`) to the type that it points to (`Usize`)
|
||||||
|
|
||||||
let _: *const usize = core::intrinsics::transmute(my_int());
|
let _: *const Usize = core::intrinsics::transmute(my_int());
|
||||||
//~^ ERROR transmute from a type (`usize`) to a pointer to that type (`*const usize`)
|
//~^ ERROR transmute from a type (`Usize`) to a pointer to that type (`*const Usize`)
|
||||||
|
|
||||||
let _: *mut usize = core::intrinsics::transmute(my_int());
|
let _: *mut Usize = core::intrinsics::transmute(my_int());
|
||||||
//~^ ERROR transmute from a type (`usize`) to a pointer to that type (`*mut usize`)
|
//~^ ERROR transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
tests/compile-fail/transmute_32bit.rs
Normal file
20
tests/compile-fail/transmute_32bit.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//ignore-x86_64
|
||||||
|
#![feature(plugin)]
|
||||||
|
#![plugin(clippy)]
|
||||||
|
|
||||||
|
#[deny(wrong_transmute)]
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
let _: *const usize = std::mem::transmute(6.0f32);
|
||||||
|
//~^ ERROR transmute from a `f32` to a pointer
|
||||||
|
|
||||||
|
let _: *mut usize = std::mem::transmute(6.0f32);
|
||||||
|
//~^ ERROR transmute from a `f32` to a pointer
|
||||||
|
|
||||||
|
let _: *const usize = std::mem::transmute('x');
|
||||||
|
//~^ ERROR transmute from a `char` to a pointer
|
||||||
|
|
||||||
|
let _: *mut usize = std::mem::transmute('x');
|
||||||
|
//~^ ERROR transmute from a `char` to a pointer
|
||||||
|
}
|
||||||
|
}
|
15
tests/compile-fail/transmute_64bit.rs
Normal file
15
tests/compile-fail/transmute_64bit.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//ignore-x86
|
||||||
|
//no-ignore-x86_64
|
||||||
|
#![feature(plugin)]
|
||||||
|
#![plugin(clippy)]
|
||||||
|
|
||||||
|
#[deny(wrong_transmute)]
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
let _: *const usize = std::mem::transmute(6.0f64);
|
||||||
|
//~^ ERROR transmute from a `f64` to a pointer
|
||||||
|
|
||||||
|
let _: *mut usize = std::mem::transmute(6.0f64);
|
||||||
|
//~^ ERROR transmute from a `f64` to a pointer
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user