mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 15:54:15 +00:00
Merge pull request #2400 from devonhollowood/misaligned-transmute
Add misaligned_transmute lint
This commit is contained in:
commit
c251120756
@ -603,6 +603,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) {
|
||||
transmute::TRANSMUTE_PTR_TO_REF,
|
||||
transmute::USELESS_TRANSMUTE,
|
||||
transmute::WRONG_TRANSMUTE,
|
||||
transmute::MISALIGNED_TRANSMUTE,
|
||||
types::ABSURD_EXTREME_COMPARISONS,
|
||||
types::BORROWED_BOX,
|
||||
types::BOX_VEC,
|
||||
|
@ -3,7 +3,8 @@ use rustc::ty::{self, Ty};
|
||||
use rustc::hir::*;
|
||||
use std::borrow::Cow;
|
||||
use syntax::ast;
|
||||
use utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then};
|
||||
use utils::{last_path_segment, match_def_path, paths, snippet, span_lint, span_lint_and_then,
|
||||
alignment};
|
||||
use utils::{opt_def_id, sugg};
|
||||
|
||||
/// **What it does:** Checks for transmutes that can't ever be correct on any
|
||||
@ -168,6 +169,23 @@ declare_lint! {
|
||||
"transmutes from an integer to a float"
|
||||
}
|
||||
|
||||
/// **What it does:** Checks for transmutes to a potentially less-aligned type.
|
||||
///
|
||||
/// **Why is this bad?** This might result in undefined behavior.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
/// ```rust
|
||||
/// // u32 is 32-bit aligned; u8 is 8-bit aligned
|
||||
/// let _: u32 = unsafe { std::mem::transmute([0u8; 4]) };
|
||||
/// ```
|
||||
declare_lint! {
|
||||
pub MISALIGNED_TRANSMUTE,
|
||||
Warn,
|
||||
"transmutes to a potentially less-aligned type"
|
||||
}
|
||||
|
||||
pub struct Transmute;
|
||||
|
||||
impl LintPass for Transmute {
|
||||
@ -180,7 +198,8 @@ impl LintPass for Transmute {
|
||||
TRANSMUTE_INT_TO_CHAR,
|
||||
TRANSMUTE_BYTES_TO_STR,
|
||||
TRANSMUTE_INT_TO_BOOL,
|
||||
TRANSMUTE_INT_TO_FLOAT
|
||||
TRANSMUTE_INT_TO_FLOAT,
|
||||
MISALIGNED_TRANSMUTE
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -201,6 +220,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Transmute {
|
||||
e.span,
|
||||
&format!("transmute from a type (`{}`) to itself", from_ty),
|
||||
),
|
||||
_ if alignment(cx, from_ty).map(|a| a.abi())
|
||||
< alignment(cx, to_ty).map(|a| a.abi())
|
||||
=> span_lint(
|
||||
cx,
|
||||
MISALIGNED_TRANSMUTE,
|
||||
e.span,
|
||||
&format!(
|
||||
"transmute from `{}` to a less-aligned type (`{}`)",
|
||||
from_ty,
|
||||
to_ty,
|
||||
)
|
||||
),
|
||||
(&ty::TyRef(_, rty), &ty::TyRawPtr(ptr_ty)) => span_lint_and_then(
|
||||
cx,
|
||||
USELESS_TRANSMUTE,
|
||||
|
@ -9,7 +9,7 @@ use rustc::lint::{LateContext, Level, Lint, LintContext};
|
||||
use rustc::session::Session;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::layout::LayoutOf;
|
||||
use rustc::ty::layout::{LayoutOf, Align};
|
||||
use rustc_errors;
|
||||
use std::borrow::Cow;
|
||||
use std::env;
|
||||
@ -1056,3 +1056,8 @@ pub fn get_arg_name(pat: &Pat) -> Option<ast::Name> {
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns alignment for a type, or None if alignment is undefined
|
||||
pub fn alignment<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, ty: Ty<'tcx>) -> Option<Align> {
|
||||
(cx.tcx, cx.param_env).layout_of(ty).ok().map(|layout| layout.align)
|
||||
}
|
||||
|
@ -140,4 +140,11 @@ fn bytes_to_str(b: &[u8], mb: &mut [u8]) {
|
||||
let _: &mut str = unsafe { std::mem::transmute(mb) };
|
||||
}
|
||||
|
||||
#[warn(misaligned_transmute)]
|
||||
fn misaligned_transmute() {
|
||||
let _: u32 = unsafe { std::mem::transmute([0u8; 4]) }; // err
|
||||
let _: u32 = unsafe { std::mem::transmute(0f32) }; // ok (alignment-wise)
|
||||
let _: [u8; 4] = unsafe { std::mem::transmute(0u32) }; // ok (alignment-wise)
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
@ -204,5 +204,13 @@ error: transmute from a `&mut [u8]` to a `&mut str`
|
||||
140 | let _: &mut str = unsafe { std::mem::transmute(mb) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
|
||||
|
||||
error: aborting due to 32 previous errors
|
||||
error: transmute from `[u8; 4]` to a less-aligned type (`u32`)
|
||||
--> $DIR/transmute.rs:145:27
|
||||
|
|
||||
145 | let _: u32 = unsafe { std::mem::transmute([0u8; 4]) }; // err
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D misaligned-transmute` implied by `-D warnings`
|
||||
|
||||
error: aborting due to 33 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user