mirror of
https://github.com/rust-lang/rust.git
synced 2026-06-02 15:56:09 +03:00
@@ -36,6 +36,9 @@ script:
|
||||
notifications:
|
||||
email:
|
||||
on_success: never
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
env:
|
||||
global:
|
||||
- RUST_TEST_NOCAPTURE=1
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ fn visit_impl_item(&mut self, _impl_item: &'hir hir::ImplItem) {}
|
||||
);
|
||||
} else if let Some((entry_node_id, _)) = *state.session.entry_fn.borrow() {
|
||||
let entry_def_id = tcx.hir.local_def_id(entry_node_id);
|
||||
let start_wrapper = tcx.lang_items.start_fn().and_then(|start_fn| {
|
||||
let start_wrapper = tcx.lang_items().start_fn().and_then(|start_fn| {
|
||||
if tcx.is_mir_available(start_fn) {
|
||||
Some(start_fn)
|
||||
} else {
|
||||
|
||||
+10
-12
@@ -96,11 +96,11 @@ fn call_c_abi(
|
||||
dest_ty: Ty<'tcx>,
|
||||
dest_block: mir::BasicBlock,
|
||||
) -> EvalResult<'tcx> {
|
||||
let name = self.tcx.item_name(def_id);
|
||||
let attrs = self.tcx.get_attrs(def_id);
|
||||
let link_name = attr::first_attr_value_str_by_name(&attrs, "link_name")
|
||||
.unwrap_or(name)
|
||||
.as_str();
|
||||
let link_name = match attr::first_attr_value_str_by_name(&attrs, "link_name") {
|
||||
Some(name) => name.as_str(),
|
||||
None => self.tcx.item_name(def_id),
|
||||
};
|
||||
|
||||
match &link_name[..] {
|
||||
"malloc" => {
|
||||
@@ -477,28 +477,26 @@ fn call_c_abi(
|
||||
|
||||
/// Get an instance for a path.
|
||||
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>> {
|
||||
let cstore = &self.tcx.sess.cstore;
|
||||
|
||||
let crates = cstore.crates();
|
||||
crates
|
||||
self.tcx
|
||||
.crates()
|
||||
.iter()
|
||||
.find(|&&krate| cstore.crate_name(krate) == path[0])
|
||||
.find(|&&krate| self.tcx.original_crate_name(krate) == path[0])
|
||||
.and_then(|krate| {
|
||||
let krate = DefId {
|
||||
krate: *krate,
|
||||
index: CRATE_DEF_INDEX,
|
||||
};
|
||||
let mut items = cstore.item_children(krate, self.tcx.sess);
|
||||
let mut items = self.tcx.item_children(krate);
|
||||
let mut path_it = path.iter().skip(1).peekable();
|
||||
|
||||
while let Some(segment) = path_it.next() {
|
||||
for item in &mem::replace(&mut items, vec![]) {
|
||||
for item in mem::replace(&mut items, Default::default()).iter() {
|
||||
if item.ident.name == *segment {
|
||||
if path_it.peek().is_none() {
|
||||
return Some(ty::Instance::mono(self.tcx, item.def.def_id()));
|
||||
}
|
||||
|
||||
items = cstore.item_children(item.def.def_id(), self.tcx.sess);
|
||||
items = self.tcx.item_children(item.def.def_id());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ fn call_intrinsic(
|
||||
) -> EvalResult<'tcx> {
|
||||
let substs = instance.substs;
|
||||
|
||||
let intrinsic_name = &self.tcx.item_name(instance.def_id()).as_str()[..];
|
||||
let intrinsic_name = &self.tcx.item_name(instance.def_id())[..];
|
||||
match intrinsic_name {
|
||||
"align_offset" => {
|
||||
// FIXME: return a real value in case the target allocation has an
|
||||
|
||||
@@ -100,7 +100,7 @@ fn visit_impl_item(&mut self, _impl_item: &'hir hir::ImplItem) {}
|
||||
state.hir_crate.unwrap().visit_all_item_likes(&mut Visitor(limits, tcx, state));
|
||||
} else if let Some((entry_node_id, _)) = *state.session.entry_fn.borrow() {
|
||||
let entry_def_id = tcx.hir.local_def_id(entry_node_id);
|
||||
let start_wrapper = tcx.lang_items.start_fn().and_then(|start_fn|
|
||||
let start_wrapper = tcx.lang_items().start_fn().and_then(|start_fn|
|
||||
if tcx.is_mir_available(start_fn) { Some(start_fn) } else { None });
|
||||
miri::eval_main(tcx, entry_def_id, start_wrapper, limits);
|
||||
|
||||
|
||||
@@ -508,8 +508,7 @@ fn collect_storage_annotations<'tcx>(mir: &'tcx mir::Mir<'tcx>) -> HashSet<mir::
|
||||
stmt: 0,
|
||||
});
|
||||
|
||||
let cur_frame = self.cur_frame();
|
||||
self.memory.set_cur_frame(cur_frame);
|
||||
self.memory.cur_frame = self.cur_frame();
|
||||
|
||||
if self.stack.len() > self.stack_limit {
|
||||
err!(StackFrameLimitReached)
|
||||
@@ -520,14 +519,13 @@ fn collect_storage_annotations<'tcx>(mir: &'tcx mir::Mir<'tcx>) -> HashSet<mir::
|
||||
|
||||
pub(super) fn pop_stack_frame(&mut self) -> EvalResult<'tcx> {
|
||||
::log_settings::settings().indentation -= 1;
|
||||
self.memory.locks_lifetime_ended(None);
|
||||
self.end_region(None)?;
|
||||
let frame = self.stack.pop().expect(
|
||||
"tried to pop a stack frame, but there were none",
|
||||
);
|
||||
if !self.stack.is_empty() {
|
||||
// TODO: IS this the correct time to start considering these accesses as originating from the returned-to stack frame?
|
||||
let cur_frame = self.cur_frame();
|
||||
self.memory.set_cur_frame(cur_frame);
|
||||
// TODO: Is this the correct time to start considering these accesses as originating from the returned-to stack frame?
|
||||
self.memory.cur_frame = self.cur_frame();
|
||||
}
|
||||
match frame.return_to_block {
|
||||
StackPopCleanup::MarkStatic(mutable) => {
|
||||
@@ -2267,7 +2265,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
|
||||
substs: ty::ClosureSubsts<'tcx>,
|
||||
) -> ty::Instance<'tcx> {
|
||||
debug!("fn_once_adapter_shim({:?}, {:?})", closure_did, substs);
|
||||
let fn_once = tcx.lang_items.fn_once_trait().unwrap();
|
||||
let fn_once = tcx.lang_items().fn_once_trait().unwrap();
|
||||
let call_once = tcx.associated_items(fn_once)
|
||||
.find(|it| it.kind == ty::AssociatedKind::Method)
|
||||
.unwrap()
|
||||
@@ -2346,7 +2344,7 @@ pub fn resolve<'a, 'tcx>(
|
||||
ty::InstanceDef::Intrinsic(def_id)
|
||||
}
|
||||
_ => {
|
||||
if Some(def_id) == tcx.lang_items.drop_in_place_fn() {
|
||||
if Some(def_id) == tcx.lang_items().drop_in_place_fn() {
|
||||
let ty = substs.type_at(0);
|
||||
if needs_drop_glue(tcx, ty) {
|
||||
debug!(" => nontrivial drop glue");
|
||||
@@ -2440,7 +2438,7 @@ fn resolve_associated_item<'a, 'tcx>(
|
||||
}
|
||||
}
|
||||
::rustc::traits::VtableClosure(closure_data) => {
|
||||
let trait_closure_kind = tcx.lang_items.fn_trait_kind(trait_id).unwrap();
|
||||
let trait_closure_kind = tcx.lang_items().fn_trait_kind(trait_id).unwrap();
|
||||
resolve_closure(
|
||||
tcx,
|
||||
closure_data.closure_def_id,
|
||||
@@ -2461,7 +2459,7 @@ fn resolve_associated_item<'a, 'tcx>(
|
||||
substs: rcvr_substs,
|
||||
}
|
||||
}
|
||||
::rustc::traits::VtableBuiltin(..) if Some(trait_id) == tcx.lang_items.clone_trait() => {
|
||||
::rustc::traits::VtableBuiltin(..) if Some(trait_id) == tcx.lang_items().clone_trait() => {
|
||||
ty::Instance {
|
||||
def: ty::InstanceDef::CloneShim(def_id, trait_ref.self_ty()),
|
||||
substs: rcvr_substs
|
||||
|
||||
@@ -268,7 +268,7 @@ pub struct Memory<'a, 'tcx, M: Machine<'tcx>> {
|
||||
writes_are_aligned: Cell<bool>,
|
||||
|
||||
/// The current stack frame. Used to check accesses against locks.
|
||||
cur_frame: usize,
|
||||
pub(super) cur_frame: usize,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> {
|
||||
@@ -530,10 +530,6 @@ pub fn check_bounds(&self, ptr: MemoryPointer, access: bool) -> EvalResult<'tcx>
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn set_cur_frame(&mut self, cur_frame: usize) {
|
||||
self.cur_frame = cur_frame;
|
||||
}
|
||||
}
|
||||
|
||||
/// Locking
|
||||
|
||||
@@ -164,7 +164,7 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> {
|
||||
}
|
||||
}
|
||||
EndRegion(ce) => {
|
||||
self.end_region(ce)?;
|
||||
self.end_region(Some(ce))?;
|
||||
}
|
||||
|
||||
// Defined to do nothing. These are added by optimization passes, to avoid changing the
|
||||
|
||||
@@ -45,6 +45,7 @@ pub(crate) fn validation_op(
|
||||
if self.tcx.sess.opts.debugging_opts.mir_emit_validate == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
debug_assert!(self.memory.cur_frame == self.cur_frame());
|
||||
|
||||
// HACK: Determine if this method is whitelisted and hence we do not perform any validation.
|
||||
// We currently insta-UB on anything passing around uninitialized memory, so we have to whitelist
|
||||
@@ -55,17 +56,17 @@ pub(crate) fn validation_op(
|
||||
use regex::Regex;
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new("^(\
|
||||
std::mem::uninitialized::|\
|
||||
std::mem::forget::|\
|
||||
(std|alloc::heap::__core)::mem::uninitialized::|\
|
||||
(std|alloc::heap::__core)::mem::forget::|\
|
||||
<(std|alloc)::heap::Heap as (std::heap|alloc::allocator)::Alloc>::|\
|
||||
<std::mem::ManuallyDrop<T>><.*>::new$|\
|
||||
<std::mem::ManuallyDrop<T> as std::ops::DerefMut><.*>::deref_mut$|\
|
||||
std::ptr::read::|\
|
||||
<(std|alloc::heap::__core)::mem::ManuallyDrop<T>><.*>::new$|\
|
||||
<(std|alloc::heap::__core)::mem::ManuallyDrop<T> as std::ops::DerefMut><.*>::deref_mut$|\
|
||||
(std|alloc::heap::__core)::ptr::read::|\
|
||||
\
|
||||
<std::sync::Arc<T>><.*>::inner$|\
|
||||
<std::sync::Arc<T>><.*>::drop_slow$|\
|
||||
(std::heap|alloc::allocator)::Layout::for_value::|\
|
||||
std::mem::(size|align)_of_val::\
|
||||
(std|alloc::heap::__core)::mem::(size|align)_of_val::\
|
||||
)").unwrap();
|
||||
}
|
||||
// Now test
|
||||
@@ -93,7 +94,8 @@ pub(crate) fn validation_op(
|
||||
if query.mutbl == MutMutable {
|
||||
let lft = DynamicLifetime {
|
||||
frame: self.cur_frame(),
|
||||
region: Some(scope),
|
||||
region: Some(scope), // Notably, we only ever suspend things for given regions.
|
||||
// Suspending for the entire function does not make any sense.
|
||||
};
|
||||
trace!("Suspending {:?} until {:?}", query, scope);
|
||||
self.suspended.entry(lft).or_insert_with(Vec::new).push(
|
||||
@@ -106,17 +108,30 @@ pub(crate) fn validation_op(
|
||||
self.validate(query, mode)
|
||||
}
|
||||
|
||||
pub(crate) fn end_region(&mut self, scope: region::Scope) -> EvalResult<'tcx> {
|
||||
self.memory.locks_lifetime_ended(Some(scope));
|
||||
// Recover suspended lvals
|
||||
let lft = DynamicLifetime {
|
||||
frame: self.cur_frame(),
|
||||
region: Some(scope),
|
||||
};
|
||||
if let Some(queries) = self.suspended.remove(&lft) {
|
||||
for query in queries {
|
||||
trace!("Recovering {:?} from suspension", query);
|
||||
self.validate(query, ValidationMode::Recover(scope))?;
|
||||
/// Release locks and executes suspensions of the given region (or the entire fn, in case of None).
|
||||
pub(crate) fn end_region(&mut self, scope: Option<region::Scope>) -> EvalResult<'tcx> {
|
||||
debug_assert!(self.memory.cur_frame == self.cur_frame());
|
||||
self.memory.locks_lifetime_ended(scope);
|
||||
match scope {
|
||||
Some(scope) => {
|
||||
// Recover suspended lvals
|
||||
let lft = DynamicLifetime {
|
||||
frame: self.cur_frame(),
|
||||
region: Some(scope),
|
||||
};
|
||||
if let Some(queries) = self.suspended.remove(&lft) {
|
||||
for query in queries {
|
||||
trace!("Recovering {:?} from suspension", query);
|
||||
self.validate(query, ValidationMode::Recover(scope))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
// Clean suspension table of current frame
|
||||
let cur_frame = self.cur_frame();
|
||||
self.suspended.retain(|lft, _| {
|
||||
lft.frame != cur_frame // keep only what is in the other (lower) frames
|
||||
});
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -543,7 +558,7 @@ fn try_validate(
|
||||
Ok(())
|
||||
}
|
||||
TyAdt(adt, subst) => {
|
||||
if Some(adt.did) == self.tcx.lang_items.unsafe_cell_type() &&
|
||||
if Some(adt.did) == self.tcx.lang_items().unsafe_cell_type() &&
|
||||
query.mutbl == MutImmutable
|
||||
{
|
||||
// No locks for shared unsafe cells. Also no other validation, the only field is private anyway.
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
// error-pattern: tried to deallocate or reallocate using incorrect alignment or size
|
||||
|
||||
use alloc::heap::*;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x = Heap.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
// error-pattern: tried to deallocate or reallocate using incorrect alignment or size
|
||||
|
||||
use alloc::heap::*;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x = Heap.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
// error-pattern: tried to deallocate dangling pointer
|
||||
|
||||
use alloc::heap::*;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x = Heap.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
// error-pattern: tried to deallocate or reallocate using incorrect alignment or size
|
||||
|
||||
use alloc::heap::*;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x = Heap.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
// error-pattern: tried to deallocate or reallocate using incorrect alignment or size
|
||||
|
||||
use alloc::heap::*;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x = Heap.alloc(Layout::from_size_align_unchecked(1, 2)).unwrap();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
// error-pattern: tried to deallocate or reallocate using incorrect alignment or size
|
||||
|
||||
use alloc::heap::*;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x = Heap.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
// error-pattern: dangling pointer was dereferenced
|
||||
|
||||
use alloc::heap::*;
|
||||
fn main() {
|
||||
unsafe {
|
||||
let x = Heap.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
#![feature(i128_type)]
|
||||
|
||||
fn b<T>(t: T) -> T { t }
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
#![feature(unsized_tuple_coercion)]
|
||||
use std::mem;
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// FIXME: Broken by #296
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct Foo<T: ?Sized> {
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// FIXME: investigate again once #296 is fixed
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
#![feature(coerce_unsized, unsize)]
|
||||
|
||||
use std::ops::CoerceUnsized;
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// FIXME: investigate again once #296 is fixed
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
// allow(const_err) to work around a bug in warnings
|
||||
#[allow(const_err)]
|
||||
static FOO: fn() = || { assert_ne!(42, 43) };
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
fn one_line_ref() -> i16 {
|
||||
*&1
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// FIXME: investigate again once #296 is fixed
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
#![feature(advanced_slice_patterns)]
|
||||
#![feature(slice_patterns)]
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// FIXME: investigate again once #296 is fixed
|
||||
// compile-flags: -Zmir-emit-validate=0
|
||||
|
||||
fn main() {
|
||||
let x = 5;
|
||||
assert_eq!(Some(&x).map(Some), Some(Some(&x)));
|
||||
|
||||
Reference in New Issue
Block a user