mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #114932 - RalfJung:miri, r=RalfJung
update Miri r? `@ghost`
This commit is contained in:
@@ -53,7 +53,7 @@ behavior** in your program, and cannot run all programs:
|
||||
positives here, so if your program runs fine in Miri right now that is by no
|
||||
means a guarantee that it is UB-free when these questions get answered.
|
||||
|
||||
In particular, Miri does currently not check that references point to valid data.
|
||||
In particular, Miri does not check that references point to valid data.
|
||||
* If the program relies on unspecified details of how data is laid out, it will
|
||||
still run fine in Miri -- but might break (including causing UB) on different
|
||||
compiler versions or different platforms.
|
||||
|
||||
@@ -1 +1 @@
|
||||
9fa6bdd764a1f7bdf69eccceeace6d13f38cb2e1
|
||||
656ee47db32e882fb02913f6204e09cc7a41a50e
|
||||
|
||||
@@ -304,11 +304,21 @@ pub fn report_error<'tcx, 'mir>(
|
||||
(None, format!("this usually indicates that your program performed an invalid operation and caused Undefined Behavior")),
|
||||
(None, format!("but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives")),
|
||||
],
|
||||
UndefinedBehavior(_) =>
|
||||
vec![
|
||||
UndefinedBehavior(info) => {
|
||||
let mut helps = vec![
|
||||
(None, format!("this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior")),
|
||||
(None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")),
|
||||
],
|
||||
];
|
||||
if let UndefinedBehaviorInfo::PointerUseAfterFree(alloc_id, _) | UndefinedBehaviorInfo::PointerOutOfBounds { alloc_id, .. } = info {
|
||||
if let Some(span) = ecx.machine.allocated_span(*alloc_id) {
|
||||
helps.push((Some(span), format!("{:?} was allocated here:", alloc_id)));
|
||||
}
|
||||
if let Some(span) = ecx.machine.deallocated_span(*alloc_id) {
|
||||
helps.push((Some(span), format!("{:?} was deallocated here:", alloc_id)));
|
||||
}
|
||||
}
|
||||
helps
|
||||
}
|
||||
InvalidProgram(
|
||||
InvalidProgramInfo::AlreadyReported(_)
|
||||
) => {
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::{
|
||||
self,
|
||||
layout::{LayoutOf, TyAndLayout},
|
||||
List, TyCtxt,
|
||||
layout::{IntegerExt as _, LayoutOf, TyAndLayout},
|
||||
List, Ty, TyCtxt,
|
||||
};
|
||||
use rustc_span::{def_id::CrateNum, sym, Span, Symbol};
|
||||
use rustc_target::abi::{Align, FieldIdx, FieldsShape, Size, Variants};
|
||||
use rustc_target::abi::{Align, FieldIdx, FieldsShape, Integer, Size, Variants};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use rand::RngCore;
|
||||
@@ -1011,6 +1011,65 @@ fn item_link_name(&self, def_id: DefId) -> Symbol {
|
||||
None => tcx.item_name(def_id),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts `f` to integer type `dest_ty` after rounding with mode `round`.
|
||||
/// Returns `None` if `f` is NaN or out of range.
|
||||
fn float_to_int_checked<F>(
|
||||
&self,
|
||||
f: F,
|
||||
dest_ty: Ty<'tcx>,
|
||||
round: rustc_apfloat::Round,
|
||||
) -> Option<Scalar<Provenance>>
|
||||
where
|
||||
F: rustc_apfloat::Float + Into<Scalar<Provenance>>,
|
||||
{
|
||||
let this = self.eval_context_ref();
|
||||
|
||||
match dest_ty.kind() {
|
||||
// Unsigned
|
||||
ty::Uint(t) => {
|
||||
let size = Integer::from_uint_ty(this, *t).size();
|
||||
let res = f.to_u128_r(size.bits_usize(), round, &mut false);
|
||||
if res.status.intersects(
|
||||
rustc_apfloat::Status::INVALID_OP
|
||||
| rustc_apfloat::Status::OVERFLOW
|
||||
| rustc_apfloat::Status::UNDERFLOW,
|
||||
) {
|
||||
// Floating point value is NaN (flagged with INVALID_OP) or outside the range
|
||||
// of values of the integer type (flagged with OVERFLOW or UNDERFLOW).
|
||||
None
|
||||
} else {
|
||||
// Floating point value can be represented by the integer type after rounding.
|
||||
// The INEXACT flag is ignored on purpose to allow rounding.
|
||||
Some(Scalar::from_uint(res.value, size))
|
||||
}
|
||||
}
|
||||
// Signed
|
||||
ty::Int(t) => {
|
||||
let size = Integer::from_int_ty(this, *t).size();
|
||||
let res = f.to_i128_r(size.bits_usize(), round, &mut false);
|
||||
if res.status.intersects(
|
||||
rustc_apfloat::Status::INVALID_OP
|
||||
| rustc_apfloat::Status::OVERFLOW
|
||||
| rustc_apfloat::Status::UNDERFLOW,
|
||||
) {
|
||||
// Floating point value is NaN (flagged with INVALID_OP) or outside the range
|
||||
// of values of the integer type (flagged with OVERFLOW or UNDERFLOW).
|
||||
None
|
||||
} else {
|
||||
// Floating point value can be represented by the integer type after rounding.
|
||||
// The INEXACT flag is ignored on purpose to allow rounding.
|
||||
Some(Scalar::from_int(res.value, size))
|
||||
}
|
||||
}
|
||||
// Nothing else
|
||||
_ =>
|
||||
span_bug!(
|
||||
this.cur_span(),
|
||||
"attempted float-to-int conversion with non-int output type {dest_ty:?}"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
};
|
||||
use rustc_span::def_id::{CrateNum, DefId};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_span::{Span, SpanData, Symbol};
|
||||
use rustc_target::abi::{Align, Size};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
@@ -135,6 +135,19 @@ fn may_leak(self) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl MiriMemoryKind {
|
||||
/// Whether we have a useful allocation span for an allocation of this kind.
|
||||
fn should_save_allocation_span(self) -> bool {
|
||||
use self::MiriMemoryKind::*;
|
||||
match self {
|
||||
// Heap allocations are fine since the `Allocation` is created immediately.
|
||||
Rust | Miri | C | WinHeap | Mmap => true,
|
||||
// Everything else is unclear, let's not show potentially confusing spans.
|
||||
Machine | Global | ExternStatic | Tls | Runtime => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MiriMemoryKind {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
use self::MiriMemoryKind::*;
|
||||
@@ -497,6 +510,10 @@ pub struct MiriMachine<'mir, 'tcx> {
|
||||
|
||||
/// Whether to collect a backtrace when each allocation is created, just in case it leaks.
|
||||
pub(crate) collect_leak_backtraces: bool,
|
||||
|
||||
/// The spans we will use to report where an allocation was created and deallocated in
|
||||
/// diagnostics.
|
||||
pub(crate) allocation_spans: RefCell<FxHashMap<AllocId, (Span, Option<Span>)>>,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
|
||||
@@ -621,6 +638,7 @@ pub(crate) fn new(config: &MiriConfig, layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>)
|
||||
stack_addr,
|
||||
stack_size,
|
||||
collect_leak_backtraces: config.collect_leak_backtraces,
|
||||
allocation_spans: RefCell::new(FxHashMap::default()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -742,6 +760,21 @@ pub(crate) fn round_up_to_multiple_of_page_size(&self, length: u64) -> Option<u6
|
||||
pub(crate) fn page_align(&self) -> Align {
|
||||
Align::from_bytes(self.page_size).unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn allocated_span(&self, alloc_id: AllocId) -> Option<SpanData> {
|
||||
self.allocation_spans
|
||||
.borrow()
|
||||
.get(&alloc_id)
|
||||
.map(|(allocated, _deallocated)| allocated.data())
|
||||
}
|
||||
|
||||
pub(crate) fn deallocated_span(&self, alloc_id: AllocId) -> Option<SpanData> {
|
||||
self.allocation_spans
|
||||
.borrow()
|
||||
.get(&alloc_id)
|
||||
.and_then(|(_allocated, deallocated)| *deallocated)
|
||||
.map(Span::data)
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitTags for MiriMachine<'_, '_> {
|
||||
@@ -791,6 +824,7 @@ fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) {
|
||||
stack_addr: _,
|
||||
stack_size: _,
|
||||
collect_leak_backtraces: _,
|
||||
allocation_spans: _,
|
||||
} = self;
|
||||
|
||||
threads.visit_tags(visit);
|
||||
@@ -1051,6 +1085,14 @@ fn adjust_allocation<'b>(
|
||||
},
|
||||
|ptr| ecx.global_base_pointer(ptr),
|
||||
)?;
|
||||
|
||||
if matches!(kind, MemoryKind::Machine(kind) if kind.should_save_allocation_span()) {
|
||||
ecx.machine
|
||||
.allocation_spans
|
||||
.borrow_mut()
|
||||
.insert(id, (ecx.machine.current_span(), None));
|
||||
}
|
||||
|
||||
Ok(Cow::Owned(alloc))
|
||||
}
|
||||
|
||||
@@ -1181,6 +1223,10 @@ fn before_memory_deallocation(
|
||||
if let Some(borrow_tracker) = &mut alloc_extra.borrow_tracker {
|
||||
borrow_tracker.before_memory_deallocation(alloc_id, prove_extra, range, machine)?;
|
||||
}
|
||||
if let Some((_, deallocated_at)) = machine.allocation_spans.borrow_mut().get_mut(&alloc_id)
|
||||
{
|
||||
*deallocated_at = Some(machine.current_span());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -27,35 +27,27 @@ impl<T> RangeMap<T> {
|
||||
#[inline(always)]
|
||||
pub fn new(size: Size, init: T) -> RangeMap<T> {
|
||||
let size = size.bytes();
|
||||
let mut map = RangeMap { v: Vec::new() };
|
||||
if size > 0 {
|
||||
map.v.push(Elem { range: 0..size, data: init });
|
||||
}
|
||||
map
|
||||
let v = if size > 0 { vec![Elem { range: 0..size, data: init }] } else { Vec::new() };
|
||||
RangeMap { v }
|
||||
}
|
||||
|
||||
/// Finds the index containing the given offset.
|
||||
fn find_offset(&self, offset: u64) -> usize {
|
||||
// We do a binary search.
|
||||
let mut left = 0usize; // inclusive
|
||||
let mut right = self.v.len(); // exclusive
|
||||
loop {
|
||||
debug_assert!(left < right, "find_offset: offset {offset} is out-of-bounds");
|
||||
let candidate = left.checked_add(right).unwrap() / 2;
|
||||
let elem = &self.v[candidate];
|
||||
if offset < elem.range.start {
|
||||
// We are too far right (offset is further left).
|
||||
debug_assert!(candidate < right); // we are making progress
|
||||
right = candidate;
|
||||
} else if offset >= elem.range.end {
|
||||
// We are too far left (offset is further right).
|
||||
debug_assert!(candidate >= left); // we are making progress
|
||||
left = candidate + 1;
|
||||
} else {
|
||||
// This is it!
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
self.v
|
||||
.binary_search_by(|elem| -> std::cmp::Ordering {
|
||||
if offset < elem.range.start {
|
||||
// We are too far right (offset is further left).
|
||||
// (`Greater` means that `elem` is greater than the desired target.)
|
||||
std::cmp::Ordering::Greater
|
||||
} else if offset >= elem.range.end {
|
||||
// We are too far left (offset is further right).
|
||||
std::cmp::Ordering::Less
|
||||
} else {
|
||||
// This is it!
|
||||
std::cmp::Ordering::Equal
|
||||
}
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Provides read-only iteration over everything in the given range. This does
|
||||
|
||||
@@ -690,6 +690,10 @@ fn emulate_foreign_item_by_name(
|
||||
let right = this.read_pointer(right)?;
|
||||
let n = Size::from_bytes(this.read_target_usize(n)?);
|
||||
|
||||
// C requires that this must always be a valid pointer (C18 §7.1.4).
|
||||
this.ptr_get_alloc_id(left)?;
|
||||
this.ptr_get_alloc_id(right)?;
|
||||
|
||||
let result = {
|
||||
let left_bytes = this.read_bytes_ptr_strip_provenance(left, n)?;
|
||||
let right_bytes = this.read_bytes_ptr_strip_provenance(right, n)?;
|
||||
@@ -714,6 +718,9 @@ fn emulate_foreign_item_by_name(
|
||||
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||
let val = val as u8;
|
||||
|
||||
// C requires that this must always be a valid pointer (C18 §7.1.4).
|
||||
this.ptr_get_alloc_id(ptr)?;
|
||||
|
||||
if let Some(idx) = this
|
||||
.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(num))?
|
||||
.iter()
|
||||
@@ -738,6 +745,9 @@ fn emulate_foreign_item_by_name(
|
||||
#[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||
let val = val as u8;
|
||||
|
||||
// C requires that this must always be a valid pointer (C18 §7.1.4).
|
||||
this.ptr_get_alloc_id(ptr)?;
|
||||
|
||||
let idx = this
|
||||
.read_bytes_ptr_strip_provenance(ptr, Size::from_bytes(num))?
|
||||
.iter()
|
||||
@@ -752,6 +762,7 @@ fn emulate_foreign_item_by_name(
|
||||
"strlen" => {
|
||||
let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
// This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
|
||||
let n = this.read_c_str(ptr)?.len();
|
||||
this.write_scalar(
|
||||
Scalar::from_target_usize(u64::try_from(n).unwrap(), this),
|
||||
@@ -791,6 +802,7 @@ fn emulate_foreign_item_by_name(
|
||||
// pointer provenance is preserved by this implementation of `strcpy`.
|
||||
// That is probably overly cautious, but there also is no fundamental
|
||||
// reason to have `strcpy` destroy pointer provenance.
|
||||
// This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
|
||||
let n = this.read_c_str(ptr_src)?.len().checked_add(1).unwrap();
|
||||
this.mem_copy(
|
||||
ptr_src,
|
||||
@@ -942,6 +954,7 @@ fn emulate_foreign_item_by_name(
|
||||
this.write_scalar(Scalar::from_u64(res.to_bits()), dest)?;
|
||||
}
|
||||
|
||||
// LLVM intrinsics
|
||||
"llvm.prefetch" => {
|
||||
let [p, rw, loc, ty] =
|
||||
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
|
||||
@@ -968,8 +981,6 @@ fn emulate_foreign_item_by_name(
|
||||
throw_unsup_format!("unsupported `llvm.prefetch` type argument: {}", ty);
|
||||
}
|
||||
}
|
||||
|
||||
// Architecture-specific shims
|
||||
"llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {
|
||||
// Computes u8+u64+u64, returning tuple (u8,u64) comprising the output carry and truncated sum.
|
||||
let [c_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
use log::trace;
|
||||
|
||||
use rustc_apfloat::{Float, Round};
|
||||
use rustc_middle::ty::layout::{IntegerExt, LayoutOf};
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_middle::{
|
||||
mir,
|
||||
ty::{self, FloatTy, Ty},
|
||||
ty::{self, FloatTy},
|
||||
};
|
||||
use rustc_target::abi::{Integer, Size};
|
||||
use rustc_target::abi::Size;
|
||||
|
||||
use crate::*;
|
||||
use atomic::EvalContextExt as _;
|
||||
@@ -356,10 +356,28 @@ fn emulate_intrinsic_by_name(
|
||||
let val = this.read_immediate(val)?;
|
||||
|
||||
let res = match val.layout.ty.kind() {
|
||||
ty::Float(FloatTy::F32) =>
|
||||
this.float_to_int_unchecked(val.to_scalar().to_f32()?, dest.layout.ty)?,
|
||||
ty::Float(FloatTy::F64) =>
|
||||
this.float_to_int_unchecked(val.to_scalar().to_f64()?, dest.layout.ty)?,
|
||||
ty::Float(FloatTy::F32) => {
|
||||
let f = val.to_scalar().to_f32()?;
|
||||
this
|
||||
.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
|
||||
.ok_or_else(|| {
|
||||
err_ub_format!(
|
||||
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{:?}`",
|
||||
dest.layout.ty
|
||||
)
|
||||
})?
|
||||
}
|
||||
ty::Float(FloatTy::F64) => {
|
||||
let f = val.to_scalar().to_f64()?;
|
||||
this
|
||||
.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
|
||||
.ok_or_else(|| {
|
||||
err_ub_format!(
|
||||
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{:?}`",
|
||||
dest.layout.ty
|
||||
)
|
||||
})?
|
||||
}
|
||||
_ =>
|
||||
span_bug!(
|
||||
this.cur_span(),
|
||||
@@ -383,57 +401,4 @@ fn emulate_intrinsic_by_name(
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn float_to_int_unchecked<F>(
|
||||
&self,
|
||||
f: F,
|
||||
dest_ty: Ty<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>>
|
||||
where
|
||||
F: Float + Into<Scalar<Provenance>>,
|
||||
{
|
||||
let this = self.eval_context_ref();
|
||||
|
||||
// Step 1: cut off the fractional part of `f`. The result of this is
|
||||
// guaranteed to be precisely representable in IEEE floats.
|
||||
let f = f.round_to_integral(Round::TowardZero).value;
|
||||
|
||||
// Step 2: Cast the truncated float to the target integer type and see if we lose any information in this step.
|
||||
Ok(match dest_ty.kind() {
|
||||
// Unsigned
|
||||
ty::Uint(t) => {
|
||||
let size = Integer::from_uint_ty(this, *t).size();
|
||||
let res = f.to_u128(size.bits_usize());
|
||||
if res.status.is_empty() {
|
||||
// No status flags means there was no further rounding or other loss of precision.
|
||||
Scalar::from_uint(res.value, size)
|
||||
} else {
|
||||
// `f` was not representable in this integer type.
|
||||
throw_ub_format!(
|
||||
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{dest_ty:?}`",
|
||||
);
|
||||
}
|
||||
}
|
||||
// Signed
|
||||
ty::Int(t) => {
|
||||
let size = Integer::from_int_ty(this, *t).size();
|
||||
let res = f.to_i128(size.bits_usize());
|
||||
if res.status.is_empty() {
|
||||
// No status flags means there was no further rounding or other loss of precision.
|
||||
Scalar::from_int(res.value, size)
|
||||
} else {
|
||||
// `f` was not representable in this integer type.
|
||||
throw_ub_format!(
|
||||
"`float_to_int_unchecked` intrinsic called on {f} which cannot be represented in target type `{dest_ty:?}`",
|
||||
);
|
||||
}
|
||||
}
|
||||
// Nothing else
|
||||
_ =>
|
||||
span_bug!(
|
||||
this.cur_span(),
|
||||
"`float_to_int_unchecked` called with non-int output type {dest_ty:?}"
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_apfloat::{Float, Round};
|
||||
use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
|
||||
use rustc_middle::{mir, ty, ty::FloatTy};
|
||||
use rustc_target::abi::{Endian, HasDataLayout, Size};
|
||||
@@ -420,7 +420,6 @@ enum Op {
|
||||
}
|
||||
}
|
||||
}
|
||||
#[rustfmt::skip]
|
||||
"cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
|
||||
let [op] = check_arg_count(args)?;
|
||||
let (op, op_len) = this.operand_to_simd(op)?;
|
||||
@@ -440,7 +439,8 @@ enum Op {
|
||||
|
||||
let val = match (op.layout.ty.kind(), dest.layout.ty.kind()) {
|
||||
// Int-to-(int|float): always safe
|
||||
(ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_)) if safe_cast || unsafe_cast =>
|
||||
(ty::Int(_) | ty::Uint(_), ty::Int(_) | ty::Uint(_) | ty::Float(_))
|
||||
if safe_cast || unsafe_cast =>
|
||||
this.int_to_int_or_float(&op, dest.layout.ty)?,
|
||||
// Float-to-float: always safe
|
||||
(ty::Float(_), ty::Float(_)) if safe_cast || unsafe_cast =>
|
||||
@@ -449,21 +449,36 @@ enum Op {
|
||||
(ty::Float(_), ty::Int(_) | ty::Uint(_)) if safe_cast =>
|
||||
this.float_to_float_or_int(&op, dest.layout.ty)?,
|
||||
// Float-to-int in unchecked mode
|
||||
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
|
||||
this.float_to_int_unchecked(op.to_scalar().to_f32()?, dest.layout.ty)?.into(),
|
||||
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast =>
|
||||
this.float_to_int_unchecked(op.to_scalar().to_f64()?, dest.layout.ty)?.into(),
|
||||
(ty::Float(FloatTy::F32), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
|
||||
let f = op.to_scalar().to_f32()?;
|
||||
this.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
|
||||
.ok_or_else(|| {
|
||||
err_ub_format!(
|
||||
"`simd_cast` intrinsic called on {f} which cannot be represented in target type `{:?}`",
|
||||
dest.layout.ty
|
||||
)
|
||||
})?
|
||||
.into()
|
||||
}
|
||||
(ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
|
||||
let f = op.to_scalar().to_f64()?;
|
||||
this.float_to_int_checked(f, dest.layout.ty, Round::TowardZero)
|
||||
.ok_or_else(|| {
|
||||
err_ub_format!(
|
||||
"`simd_cast` intrinsic called on {f} which cannot be represented in target type `{:?}`",
|
||||
dest.layout.ty
|
||||
)
|
||||
})?
|
||||
.into()
|
||||
}
|
||||
// Ptr-to-ptr cast
|
||||
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast => {
|
||||
this.ptr_to_ptr(&op, dest.layout.ty)?
|
||||
}
|
||||
(ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast =>
|
||||
this.ptr_to_ptr(&op, dest.layout.ty)?,
|
||||
// Ptr/Int casts
|
||||
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast => {
|
||||
this.pointer_expose_address_cast(&op, dest.layout.ty)?
|
||||
}
|
||||
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast => {
|
||||
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?
|
||||
}
|
||||
(ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast =>
|
||||
this.pointer_expose_address_cast(&op, dest.layout.ty)?,
|
||||
(ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast =>
|
||||
this.pointer_from_exposed_address_cast(&op, dest.layout.ty)?,
|
||||
// Error otherwise
|
||||
_ =>
|
||||
throw_unsup_format!(
|
||||
|
||||
@@ -195,24 +195,12 @@ fn emulate_x86_sse_intrinsic(
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut exact = false;
|
||||
let cvt = op.to_i128_r(32, rnd, &mut exact);
|
||||
let res = if cvt.status.intersects(
|
||||
rustc_apfloat::Status::INVALID_OP
|
||||
| rustc_apfloat::Status::OVERFLOW
|
||||
| rustc_apfloat::Status::UNDERFLOW,
|
||||
) {
|
||||
// Input is NaN (flagged with INVALID_OP) or does not fit
|
||||
// in an i32 (flagged with OVERFLOW or UNDERFLOW), fallback
|
||||
// to minimum acording to SSE semantics. The INEXACT flag
|
||||
// is ignored on purpose because rounding can happen during
|
||||
// float-to-int conversion.
|
||||
i32::MIN
|
||||
} else {
|
||||
i32::try_from(cvt.value).unwrap()
|
||||
};
|
||||
let res = this.float_to_int_checked(op, dest.layout.ty, rnd).unwrap_or_else(|| {
|
||||
// Fallback to minimum acording to SSE semantics.
|
||||
Scalar::from_i32(i32::MIN)
|
||||
});
|
||||
|
||||
this.write_scalar(Scalar::from_i32(res), dest)?;
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
// Use to implement _mm_cvtss_si64 and _mm_cvttss_si64.
|
||||
// Converts the first component of `op` from f32 to i64.
|
||||
@@ -232,24 +220,12 @@ fn emulate_x86_sse_intrinsic(
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut exact = false;
|
||||
let cvt = op.to_i128_r(64, rnd, &mut exact);
|
||||
let res = if cvt.status.intersects(
|
||||
rustc_apfloat::Status::INVALID_OP
|
||||
| rustc_apfloat::Status::OVERFLOW
|
||||
| rustc_apfloat::Status::UNDERFLOW,
|
||||
) {
|
||||
// Input is NaN (flagged with INVALID_OP) or does not fit
|
||||
// in an i64 (flagged with OVERFLOW or UNDERFLOW), fallback
|
||||
// to minimum acording to SSE semantics. The INEXACT flag
|
||||
// is ignored on purpose because rounding can happen during
|
||||
// float-to-int conversion.
|
||||
i64::MIN
|
||||
} else {
|
||||
i64::try_from(cvt.value).unwrap()
|
||||
};
|
||||
let res = this.float_to_int_checked(op, dest.layout.ty, rnd).unwrap_or_else(|| {
|
||||
// Fallback to minimum acording to SSE semantics.
|
||||
Scalar::from_i64(i64::MIN)
|
||||
});
|
||||
|
||||
this.write_scalar(Scalar::from_i64(res), dest)?;
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
// Used to implement the _mm_cvtsi32_ss function.
|
||||
// Converts `right` from i32 to f32. Returns a SIMD vector with
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | unsafe { __rust_dealloc(ptr, layout.size(), layout.align()) }
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/deallocate-twice.rs:LL:CC
|
||||
|
|
||||
LL | let x = alloc(Layout::from_size_align_unchecked(1, 1));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/deallocate-twice.rs:LL:CC
|
||||
|
|
||||
LL | dealloc(x, Layout::from_size_align_unchecked(1, 1));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `std::alloc::dealloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/deallocate-twice.rs:LL:CC
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | let _z = *x;
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/reallocate-change-alloc.rs:LL:CC
|
||||
|
|
||||
LL | let x = alloc(Layout::from_size_align_unchecked(1, 1));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/reallocate-change-alloc.rs:LL:CC
|
||||
|
|
||||
LL | let _y = realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/reallocate-change-alloc.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | unsafe { __rust_realloc(ptr, layout.size(), layout.align(), new_size) }
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/reallocate-dangling.rs:LL:CC
|
||||
|
|
||||
LL | let x = alloc(Layout::from_size_align_unchecked(1, 1));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/reallocate-dangling.rs:LL:CC
|
||||
|
|
||||
LL | dealloc(x, Layout::from_size_align_unchecked(1, 1));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `std::alloc::realloc` at RUSTLIB/alloc/src/alloc.rs:LL:CC
|
||||
note: inside `main`
|
||||
--> $DIR/reallocate-dangling.rs:LL:CC
|
||||
|
||||
@@ -6,7 +6,12 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/issue-miri-1050-1.rs:LL:CC
|
||||
|
|
||||
LL | let ptr = Box::into_raw(Box::new(0u16));
|
||||
| ^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `std::boxed::Box::<u32>::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC
|
||||
= note: inside `std::boxed::Box::<u32>::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC
|
||||
note: inside `main`
|
||||
|
||||
@@ -6,7 +6,12 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/issue-miri-1050-1.rs:LL:CC
|
||||
|
|
||||
LL | let ptr = Box::into_raw(Box::new(0u16));
|
||||
| ^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `std::boxed::Box::<u32>::from_raw_in` at RUSTLIB/alloc/src/boxed.rs:LL:CC
|
||||
= note: inside `std::boxed::Box::<u32>::from_raw` at RUSTLIB/alloc/src/boxed.rs:LL:CC
|
||||
note: inside `main`
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | let x = unsafe { ptr::addr_of!(*p) };
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/dangling_pointer_addr_of.rs:LL:CC
|
||||
|
|
||||
LL | let b = Box::new(42);
|
||||
| ^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/dangling_pointer_addr_of.rs:LL:CC
|
||||
|
|
||||
LL | };
|
||||
| ^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
|
||||
= note: this error originates in the macro `ptr::addr_of` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | let x = unsafe { *p };
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/dangling_pointer_deref.rs:LL:CC
|
||||
|
|
||||
LL | let b = Box::new(42);
|
||||
| ^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/dangling_pointer_deref.rs:LL:CC
|
||||
|
|
||||
LL | };
|
||||
| ^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/dangling_pointer_deref.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | let x = unsafe { p.offset(42) };
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/dangling_pointer_offset.rs:LL:CC
|
||||
|
|
||||
LL | let b = Box::new(42);
|
||||
| ^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/dangling_pointer_offset.rs:LL:CC
|
||||
|
|
||||
LL | };
|
||||
| ^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/dangling_pointer_offset.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
+11
-1
@@ -6,7 +6,17 @@ LL | let _ = *p;
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/dangling_pointer_project_underscore.rs:LL:CC
|
||||
|
|
||||
LL | let b = Box::new(42);
|
||||
| ^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/dangling_pointer_project_underscore.rs:LL:CC
|
||||
|
|
||||
LL | };
|
||||
| ^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/dangling_pointer_project_underscore.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | let _x = unsafe { *p };
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/dangling_zst_deref.rs:LL:CC
|
||||
|
|
||||
LL | let b = Box::new(42);
|
||||
| ^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/dangling_zst_deref.rs:LL:CC
|
||||
|
|
||||
LL | };
|
||||
| ^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/dangling_zst_deref.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -6,8 +6,14 @@ LL | let x = unsafe { *v.as_ptr().wrapping_offset(5) };
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/out_of_bounds_read1.rs:LL:CC
|
||||
|
|
||||
LL | let v: Vec<u8> = vec![1, 2];
|
||||
| ^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/out_of_bounds_read1.rs:LL:CC
|
||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
|
||||
@@ -6,8 +6,14 @@ LL | let x = unsafe { *v.as_ptr().wrapping_offset(5) };
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/out_of_bounds_read2.rs:LL:CC
|
||||
|
|
||||
LL | let v: Vec<u8> = vec![1, 2];
|
||||
| ^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/out_of_bounds_read2.rs:LL:CC
|
||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
|
||||
@@ -6,7 +6,21 @@ LL | *ptr.0
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/dealloc_read_race2.rs:LL:CC
|
||||
|
|
||||
LL | let pointer: *mut usize = Box::into_raw(Box::new(0usize));
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/dealloc_read_race2.rs:LL:CC
|
||||
|
|
||||
LL | / __rust_dealloc(
|
||||
LL | | ptr.0 as *mut _,
|
||||
LL | | std::mem::size_of::<usize>(),
|
||||
LL | | std::mem::align_of::<usize>(),
|
||||
LL | | )
|
||||
| |_____________^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside closure at $DIR/dealloc_read_race2.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -6,7 +6,21 @@ LL | *ptr.0 = 2;
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/dealloc_write_race2.rs:LL:CC
|
||||
|
|
||||
LL | let pointer: *mut usize = Box::into_raw(Box::new(0usize));
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/dealloc_write_race2.rs:LL:CC
|
||||
|
|
||||
LL | / __rust_dealloc(
|
||||
LL | | ptr.0 as *mut _,
|
||||
LL | | std::mem::size_of::<usize>(),
|
||||
LL | | std::mem::align_of::<usize>(),
|
||||
LL | | );
|
||||
| |_____________^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside closure at $DIR/dealloc_write_race2.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | *num += 1;
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/generator-pinned-moved.rs:LL:CC
|
||||
|
|
||||
LL | let mut generator_iterator = Box::new(GeneratorIteratorAdapter(firstn()));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/generator-pinned-moved.rs:LL:CC
|
||||
|
|
||||
LL | }; // *deallocate* generator_iterator
|
||||
| ^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside closure at $DIR/generator-pinned-moved.rs:LL:CC
|
||||
note: inside `<GeneratorIteratorAdapter<[static generator@$DIR/generator-pinned-moved.rs:LL:CC]> as std::iter::Iterator>::next`
|
||||
--> $DIR/generator-pinned-moved.rs:LL:CC
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -1 which cannot be represented in target type `u128`
|
||||
error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on -1.0000000000000999 which cannot be represented in target type `u128`
|
||||
--> $DIR/float_to_int_64_neg.rs:LL:CC
|
||||
|
|
||||
LL | float_to_int_unchecked::<f64, u128>(-1.0000000000001f64);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -1 which cannot be represented in target type `u128`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on -1.0000000000000999 which cannot be represented in target type `u128`
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
||||
@@ -6,7 +6,12 @@ LL | let _x = unsafe { x.offset(0) }; // UB despite offset 0, the pointer is
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/ptr_offset_ptr_plus_0.rs:LL:CC
|
||||
|
|
||||
LL | let x = Box::into_raw(Box::new(0u32));
|
||||
| ^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/ptr_offset_ptr_plus_0.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
error: Undefined Behavior: `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
||||
error: Undefined Behavior: `simd_cast` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
||||
--> $DIR/simd-float-to-int.rs:LL:CC
|
||||
|
|
||||
LL | let _x: i32x2 = f32x2::from_array([f32::MAX, f32::MIN]).to_int_unchecked();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `float_to_int_unchecked` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `simd_cast` intrinsic called on 3.40282347E+38 which cannot be represented in target type `i32`
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
||||
@@ -11,8 +11,14 @@ LL | | );
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/simd-scatter.rs:LL:CC
|
||||
|
|
||||
LL | let mut vec: Vec<i8> = vec![10, 11, 12, 13, 14, 15, 16, 17, 18];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/simd-scatter.rs:LL:CC
|
||||
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | assert_eq!(42, **unsafe { &*Weak::as_ptr(&weak) });
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/rc_as_ptr.rs:LL:CC
|
||||
|
|
||||
LL | let strong = Rc::new(Box::new(42));
|
||||
| ^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/rc_as_ptr.rs:LL:CC
|
||||
|
|
||||
LL | drop(strong);
|
||||
| ^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at RUSTLIB/core/src/macros/mod.rs:LL:CC
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||
error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
||||
--> $DIR/memchr_null.rs:LL:CC
|
||||
|
|
||||
LL | libc::memchr(ptr::null(), 0, 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||
error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
||||
--> $DIR/memcmp_null.rs:LL:CC
|
||||
|
|
||||
LL | libc::memcmp(ptr::null(), ptr::null(), 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//@ignore-target-windows: No libc on Windows
|
||||
//@compile-flags: -Zmiri-permissive-provenance
|
||||
|
||||
// C says that passing "invalid" pointers is UB for all string functions.
|
||||
// It is unclear whether `(int*)42` is "invalid", but there is no actually
|
||||
// a `char` living at that address, so arguably it cannot be a valid pointer.
|
||||
// Hence this is UB.
|
||||
fn main() {
|
||||
let ptr = 42 as *const u8;
|
||||
unsafe {
|
||||
libc::memcmp(ptr.cast(), ptr.cast(), 0); //~ERROR: dangling
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
error: Undefined Behavior: out-of-bounds pointer use: 0x2a[noalloc] is a dangling pointer (it has no provenance)
|
||||
--> $DIR/memcmp_zero.rs:LL:CC
|
||||
|
|
||||
LL | libc::memcmp(ptr.cast(), ptr.cast(), 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: 0x2a[noalloc] is a dangling pointer (it has no provenance)
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
= note: inside `main` at $DIR/memcmp_zero.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||
error: Undefined Behavior: out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
||||
--> $DIR/memrchr_null.rs:LL:CC
|
||||
|
|
||||
LL | libc::memrchr(ptr::null(), 0, 0);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
|
||||
@@ -21,7 +21,24 @@ LL | let _x = *(ptr as *mut u8);
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/mmap_use_after_munmap.rs:LL:CC
|
||||
|
|
||||
LL | let ptr = libc::mmap(
|
||||
| ___________________^
|
||||
LL | | std::ptr::null_mut(),
|
||||
LL | | 4096,
|
||||
LL | | libc::PROT_READ | libc::PROT_WRITE,
|
||||
... |
|
||||
LL | | 0,
|
||||
LL | | );
|
||||
| |_________^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/mmap_use_after_munmap.rs:LL:CC
|
||||
|
|
||||
LL | libc::munmap(ptr, 4096);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/mmap_use_after_munmap.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -6,7 +6,17 @@ LL | unsafe { *x = zst_val };
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/zst2.rs:LL:CC
|
||||
|
|
||||
LL | let mut x_box = Box::new(1u8);
|
||||
| ^^^^^^^^^^^^^
|
||||
help: ALLOC was deallocated here:
|
||||
--> $DIR/zst2.rs:LL:CC
|
||||
|
|
||||
LL | drop(x_box);
|
||||
| ^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/zst2.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
@@ -6,7 +6,12 @@ LL | unsafe { *(x as *mut [u8; 0]) = zst_val };
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
help: ALLOC was allocated here:
|
||||
--> $DIR/zst3.rs:LL:CC
|
||||
|
|
||||
LL | let mut x_box = Box::new(1u8);
|
||||
| ^^^^^^^^^^^^^
|
||||
= note: BACKTRACE (of the first span):
|
||||
= note: inside `main` at $DIR/zst3.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
Reference in New Issue
Block a user