make writes_through_immutable_pointer a hard error
This commit is contained in:
parent
355a307a87
commit
8b642a1883
7 changed files with 23 additions and 102 deletions
|
@ -22,6 +22,7 @@ pub enum ConstEvalErrKind {
|
||||||
RecursiveStatic,
|
RecursiveStatic,
|
||||||
AssertFailure(AssertKind<ConstInt>),
|
AssertFailure(AssertKind<ConstInt>),
|
||||||
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
|
Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
|
||||||
|
WriteThroughImmutablePointer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MachineStopType for ConstEvalErrKind {
|
impl MachineStopType for ConstEvalErrKind {
|
||||||
|
@ -35,12 +36,16 @@ impl MachineStopType for ConstEvalErrKind {
|
||||||
Panic { .. } => const_eval_panic,
|
Panic { .. } => const_eval_panic,
|
||||||
RecursiveStatic => const_eval_recursive_static,
|
RecursiveStatic => const_eval_recursive_static,
|
||||||
AssertFailure(x) => x.diagnostic_message(),
|
AssertFailure(x) => x.diagnostic_message(),
|
||||||
|
WriteThroughImmutablePointer => const_eval_write_through_immutable_pointer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagArgName, DiagArgValue)) {
|
fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagArgName, DiagArgValue)) {
|
||||||
use ConstEvalErrKind::*;
|
use ConstEvalErrKind::*;
|
||||||
match *self {
|
match *self {
|
||||||
RecursiveStatic | ConstAccessesMutGlobal | ModifiedGlobal => {}
|
RecursiveStatic
|
||||||
|
| ConstAccessesMutGlobal
|
||||||
|
| ModifiedGlobal
|
||||||
|
| WriteThroughImmutablePointer => {}
|
||||||
AssertFailure(kind) => kind.add_args(adder),
|
AssertFailure(kind) => kind.add_args(adder),
|
||||||
Panic { msg, line, col, file } => {
|
Panic { msg, line, col, file } => {
|
||||||
adder("msg".into(), msg.into_diag_arg());
|
adder("msg".into(), msg.into_diag_arg());
|
||||||
|
@ -159,6 +164,7 @@ where
|
||||||
|
|
||||||
/// Emit a lint from a const-eval situation, with a backtrace.
|
/// Emit a lint from a const-eval situation, with a backtrace.
|
||||||
// Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future!
|
// Even if this is unused, please don't remove it -- chances are we will need to emit a lint during const-eval again in the future!
|
||||||
|
#[allow(unused)]
|
||||||
pub(super) fn lint<'tcx, L>(
|
pub(super) fn lint<'tcx, L>(
|
||||||
tcx: TyCtxtAt<'tcx>,
|
tcx: TyCtxtAt<'tcx>,
|
||||||
machine: &CompileTimeMachine<'tcx>,
|
machine: &CompileTimeMachine<'tcx>,
|
||||||
|
|
|
@ -12,7 +12,6 @@ use rustc_middle::query::TyCtxtAt;
|
||||||
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
|
use rustc_middle::ty::layout::{FnAbiOf, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_middle::{bug, mir};
|
use rustc_middle::{bug, mir};
|
||||||
use rustc_session::lint::builtin::WRITES_THROUGH_IMMUTABLE_POINTER;
|
|
||||||
use rustc_span::symbol::{sym, Symbol};
|
use rustc_span::symbol::{sym, Symbol};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use rustc_target::abi::{Align, Size};
|
use rustc_target::abi::{Align, Size};
|
||||||
|
@ -729,8 +728,8 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before_memory_write(
|
fn before_memory_write(
|
||||||
tcx: TyCtxtAt<'tcx>,
|
_tcx: TyCtxtAt<'tcx>,
|
||||||
machine: &mut Self,
|
_machine: &mut Self,
|
||||||
_alloc_extra: &mut Self::AllocExtra,
|
_alloc_extra: &mut Self::AllocExtra,
|
||||||
(_alloc_id, immutable): (AllocId, bool),
|
(_alloc_id, immutable): (AllocId, bool),
|
||||||
range: AllocRange,
|
range: AllocRange,
|
||||||
|
@ -741,9 +740,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
|
||||||
}
|
}
|
||||||
// Reject writes through immutable pointers.
|
// Reject writes through immutable pointers.
|
||||||
if immutable {
|
if immutable {
|
||||||
super::lint(tcx, machine, WRITES_THROUGH_IMMUTABLE_POINTER, |frames| {
|
return Err(ConstEvalErrKind::WriteThroughImmutablePointer.into());
|
||||||
crate::errors::WriteThroughImmutablePointer { frames }
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// Everything else is fine.
|
// Everything else is fine.
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -407,13 +407,6 @@ pub struct ConstEvalError {
|
||||||
pub frame_notes: Vec<FrameNote>,
|
pub frame_notes: Vec<FrameNote>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(LintDiagnostic)]
|
|
||||||
#[diag(const_eval_write_through_immutable_pointer)]
|
|
||||||
pub struct WriteThroughImmutablePointer {
|
|
||||||
#[subdiagnostic]
|
|
||||||
pub frames: Vec<FrameNote>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(const_eval_nullary_intrinsic_fail)]
|
#[diag(const_eval_nullary_intrinsic_fail)]
|
||||||
pub struct NullaryIntrinsicError {
|
pub struct NullaryIntrinsicError {
|
||||||
|
|
|
@ -569,7 +569,8 @@ fn register_builtins(store: &mut LintStore) {
|
||||||
"byte_slice_in_packed_struct_with_derive",
|
"byte_slice_in_packed_struct_with_derive",
|
||||||
"converted into hard error, see issue #107457 \
|
"converted into hard error, see issue #107457 \
|
||||||
<https://github.com/rust-lang/rust/issues/107457> for more information",
|
<https://github.com/rust-lang/rust/issues/107457> for more information",
|
||||||
)
|
);
|
||||||
|
store.register_removed("writes_through_immutable_pointer", "converted into hard error");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_internals(store: &mut LintStore) {
|
fn register_internals(store: &mut LintStore) {
|
||||||
|
|
|
@ -142,7 +142,6 @@ declare_lint_pass! {
|
||||||
USELESS_DEPRECATED,
|
USELESS_DEPRECATED,
|
||||||
WARNINGS,
|
WARNINGS,
|
||||||
WASM_C_ABI,
|
WASM_C_ABI,
|
||||||
WRITES_THROUGH_IMMUTABLE_POINTER,
|
|
||||||
// tidy-alphabetical-end
|
// tidy-alphabetical-end
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -4696,40 +4695,6 @@ declare_lint! {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
declare_lint! {
|
|
||||||
/// The `writes_through_immutable_pointer` lint detects writes through pointers derived from
|
|
||||||
/// shared references.
|
|
||||||
///
|
|
||||||
/// ### Example
|
|
||||||
///
|
|
||||||
/// ```rust,compile_fail
|
|
||||||
/// #![feature(const_mut_refs)]
|
|
||||||
/// const WRITE_AFTER_CAST: () = unsafe {
|
|
||||||
/// let mut x = 0;
|
|
||||||
/// let ptr = &x as *const i32 as *mut i32;
|
|
||||||
/// *ptr = 0;
|
|
||||||
/// };
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// {{produces}}
|
|
||||||
///
|
|
||||||
/// ### Explanation
|
|
||||||
///
|
|
||||||
/// Shared references are immutable (when there is no `UnsafeCell` involved),
|
|
||||||
/// and writing through them or through pointers derived from them is Undefined Behavior.
|
|
||||||
/// The compiler recently learned to detect such Undefined Behavior during compile-time
|
|
||||||
/// evaluation, and in the future this will raise a hard error.
|
|
||||||
///
|
|
||||||
/// [future-incompatible]: ../index.md#future-incompatible-lints
|
|
||||||
pub WRITES_THROUGH_IMMUTABLE_POINTER,
|
|
||||||
Warn,
|
|
||||||
"shared references are immutable, and pointers derived from them must not be written to",
|
|
||||||
@future_incompatible = FutureIncompatibleInfo {
|
|
||||||
reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
|
|
||||||
reference: "issue #X <https://github.com/rust-lang/rust/issues/X>",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
declare_lint! {
|
declare_lint! {
|
||||||
/// The `private_macro_use` lint detects private macros that are imported
|
/// The `private_macro_use` lint detects private macros that are imported
|
||||||
/// with `#[macro_use]`.
|
/// with `#[macro_use]`.
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//! Ensure we catch UB due to writing through a shared reference.
|
//! Ensure we catch UB due to writing through a shared reference.
|
||||||
#![feature(const_mut_refs, const_refs_to_cell)]
|
#![feature(const_mut_refs, const_refs_to_cell)]
|
||||||
#![deny(writes_through_immutable_pointer)]
|
|
||||||
#![allow(invalid_reference_casting)]
|
#![allow(invalid_reference_casting)]
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -9,15 +8,15 @@ use std::cell::UnsafeCell;
|
||||||
const WRITE_AFTER_CAST: () = unsafe {
|
const WRITE_AFTER_CAST: () = unsafe {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let ptr = &x as *const i32 as *mut i32;
|
let ptr = &x as *const i32 as *mut i32;
|
||||||
*ptr = 0; //~ERROR: writes_through_immutable_pointer
|
*ptr = 0; //~ERROR: evaluation of constant value failed
|
||||||
//~^ previously accepted
|
//~| immutable
|
||||||
};
|
};
|
||||||
|
|
||||||
const WRITE_AFTER_TRANSMUTE: () = unsafe {
|
const WRITE_AFTER_TRANSMUTE: () = unsafe {
|
||||||
let mut x = 0;
|
let mut x = 0;
|
||||||
let ptr: *mut i32 = mem::transmute(&x);
|
let ptr: *mut i32 = mem::transmute(&x);
|
||||||
*ptr = 0; //~ERROR: writes_through_immutable_pointer
|
*ptr = 0; //~ERROR: evaluation of constant value failed
|
||||||
//~^ previously accepted
|
//~| immutable
|
||||||
};
|
};
|
||||||
|
|
||||||
// it's okay when there is interior mutability;
|
// it's okay when there is interior mutability;
|
||||||
|
|
|
@ -1,55 +1,15 @@
|
||||||
error: writing through a pointer that was derived from a shared (immutable) reference
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/ub-write-through-immutable.rs:12:5
|
--> $DIR/ub-write-through-immutable.rs:11:5
|
||||||
|
|
|
|
||||||
LL | *ptr = 0;
|
LL | *ptr = 0;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/ub-write-through-immutable.rs:3:9
|
|
||||||
|
|
|
||||||
LL | #![deny(writes_through_immutable_pointer)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: writing through a pointer that was derived from a shared (immutable) reference
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/ub-write-through-immutable.rs:19:5
|
--> $DIR/ub-write-through-immutable.rs:18:5
|
||||||
|
|
|
|
||||||
LL | *ptr = 0;
|
LL | *ptr = 0;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^ writing through a pointer that was derived from a shared (immutable) reference
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X>
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Future incompatibility report: Future breakage diagnostic:
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
error: writing through a pointer that was derived from a shared (immutable) reference
|
|
||||||
--> $DIR/ub-write-through-immutable.rs:12:5
|
|
||||||
|
|
|
||||||
LL | *ptr = 0;
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/ub-write-through-immutable.rs:3:9
|
|
||||||
|
|
|
||||||
LL | #![deny(writes_through_immutable_pointer)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
Future breakage diagnostic:
|
|
||||||
error: writing through a pointer that was derived from a shared (immutable) reference
|
|
||||||
--> $DIR/ub-write-through-immutable.rs:19:5
|
|
||||||
|
|
|
||||||
LL | *ptr = 0;
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #X <https://github.com/rust-lang/rust/issues/X>
|
|
||||||
note: the lint level is defined here
|
|
||||||
--> $DIR/ub-write-through-immutable.rs:3:9
|
|
||||||
|
|
|
||||||
LL | #![deny(writes_through_immutable_pointer)]
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue