mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
WIP PROOF-OF-CONCEPT: Make the compiler complain about all int<->ptr casts.
ALL OF THEM
This commit is contained in:
parent
e4f5b15b88
commit
1040cab53b
@ -2648,6 +2648,41 @@ declare_lint! {
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `fuzzy_provenance_casts` lint detects an `as` cast between an integer
|
||||
/// and a pointer.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// fn main() {
|
||||
/// let my_ref = &0;
|
||||
/// let my_addr = my_ref as usize;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// Casting a pointer to an integer or an integer to a pointer is a lossy operation,
|
||||
/// because beyond just an *address* a pointer may be associated with a particular
|
||||
/// *provenance* and *segment*. This information is required by both the compiler
|
||||
/// and the hardware to correctly execute your code. If you need to do this kind
|
||||
/// of operation, use ptr::addr and ptr::with_addr.
|
||||
///
|
||||
/// This is a [future-incompatible] lint to transition this to a hard error
|
||||
/// in the future. See [issue #9999999] for more details.
|
||||
///
|
||||
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
||||
/// [issue #9999999]: https://github.com/rust-lang/rust/issues/9999999
|
||||
pub FUZZY_PROVENANCE_CASTS,
|
||||
Warn,
|
||||
"A lossy pointer-integer integer cast is used",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reference: "issue #9999999 <https://github.com/rust-lang/rust/issues/9999999>",
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `const_evaluatable_unchecked` lint detects a generic constant used
|
||||
/// in a type.
|
||||
@ -3101,6 +3136,7 @@ declare_lint_pass! {
|
||||
UNSAFE_OP_IN_UNSAFE_FN,
|
||||
INCOMPLETE_INCLUDE,
|
||||
CENUM_IMPL_DROP_CAST,
|
||||
FUZZY_PROVENANCE_CASTS,
|
||||
CONST_EVALUATABLE_UNCHECKED,
|
||||
INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
|
||||
MUST_NOT_SUSPEND,
|
||||
|
@ -807,11 +807,22 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||
|
||||
// ptr -> *
|
||||
(Ptr(m_e), Ptr(m_c)) => self.check_ptr_ptr_cast(fcx, m_e, m_c), // ptr-ptr-cast
|
||||
(Ptr(m_expr), Int(_)) => self.check_ptr_addr_cast(fcx, m_expr), // ptr-addr-cast
|
||||
(FnPtr, Int(_)) => Ok(CastKind::FnPtrAddrCast),
|
||||
|
||||
// * -> ptr
|
||||
(Int(_), Ptr(mt)) => self.check_addr_ptr_cast(fcx, mt), // addr-ptr-cast
|
||||
// ptr-addr-cast
|
||||
(Ptr(m_expr), Int(_)) => {
|
||||
self.fuzzy_provenance_ptr2int_lint(fcx, t_from);
|
||||
self.check_ptr_addr_cast(fcx, m_expr)
|
||||
}
|
||||
(FnPtr, Int(_)) => {
|
||||
self.fuzzy_provenance_ptr2int_lint(fcx, t_from);
|
||||
Ok(CastKind::FnPtrAddrCast)
|
||||
}
|
||||
// addr-ptr-cast
|
||||
(Int(_), Ptr(mt)) => {
|
||||
self.fuzzy_provenance_int2ptr_lint(fcx);
|
||||
self.check_addr_ptr_cast(fcx, mt)
|
||||
}
|
||||
// fn-ptr-cast
|
||||
(FnPtr, Ptr(mt)) => self.check_fptr_ptr_cast(fcx, mt),
|
||||
|
||||
// prim -> prim
|
||||
@ -934,6 +945,7 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||
fcx: &FnCtxt<'a, 'tcx>,
|
||||
m_cast: TypeAndMut<'tcx>,
|
||||
) -> Result<CastKind, CastError> {
|
||||
self.fuzzy_provenance_int2ptr_lint(fcx);
|
||||
// ptr-addr cast. pointer must be thin.
|
||||
match fcx.pointer_kind(m_cast.ty, self.span)? {
|
||||
None => Err(CastError::UnknownCastPtrKind),
|
||||
@ -973,6 +985,50 @@ impl<'a, 'tcx> CastCheck<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fuzzy_provenance_ptr2int_lint(&self, fcx: &FnCtxt<'a, 'tcx>, t_from: CastTy<'tcx>) {
|
||||
fcx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::FUZZY_PROVENANCE_CASTS,
|
||||
self.expr.hir_id,
|
||||
self.span,
|
||||
|err| {
|
||||
let mut err = err.build(&format!(
|
||||
"strict provenance disallows casting pointer `{}` to integer `{}`",
|
||||
self.expr_ty, self.cast_ty
|
||||
));
|
||||
|
||||
if let CastTy::FnPtr = t_from {
|
||||
err.help(
|
||||
"use `(... as *const u8).addr()` to obtain \
|
||||
the address of a function pointer",
|
||||
);
|
||||
} else {
|
||||
err.help("use `.addr()` to obtain the address of a pointer");
|
||||
}
|
||||
|
||||
err.emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn fuzzy_provenance_int2ptr_lint(&self, fcx: &FnCtxt<'a, 'tcx>) {
|
||||
fcx.tcx.struct_span_lint_hir(
|
||||
lint::builtin::FUZZY_PROVENANCE_CASTS,
|
||||
self.expr.hir_id,
|
||||
self.span,
|
||||
|err| {
|
||||
err.build(&format!(
|
||||
"strict provenance disallows casting integer `{}` to pointer `{}`",
|
||||
self.expr_ty, self.cast_ty
|
||||
))
|
||||
.help(
|
||||
"use `.with_addr(...)` to adjust a valid pointer \
|
||||
in the same allocation, to this address",
|
||||
)
|
||||
.emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
Loading…
Reference in New Issue
Block a user