Skip to content
This repository has been archived by the owner on Aug 22, 2024. It is now read-only.

Commit

Permalink
Roll back to nightly-2019-07-08 for release to LIBRA
Browse files Browse the repository at this point in the history
  • Loading branch information
Herman Venter committed Sep 19, 2019
1 parent 3b7338f commit ef1fb94
Show file tree
Hide file tree
Showing 13 changed files with 88 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ os:
- windows
language: rust
rust:
- nightly-2019-08-12
- nightly-2019-07-08

before_install:
- if [ ${TRAVIS_OS_NAME} == "osx" ]; then curl -L https://github.com/mozilla/grcov/releases/download/v0.4.3/grcov-osx-x86_64.tar.bz2 | tar jxf -; fi
Expand Down
14 changes: 4 additions & 10 deletions checker/src/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use log_derive::{logfn, logfn_inputs};
use mirai_annotations::assume;
use rustc::hir::def_id::DefId;
use rustc::ty::TyCtxt;
use rustc_driver::Compilation;
use rustc_interface::interface;
use std::collections::{HashMap, HashSet};
use std::fmt::{Debug, Formatter, Result};
Expand Down Expand Up @@ -92,7 +91,7 @@ impl rustc_driver::Callbacks for MiraiCallbacks {
/// interpretation of all of the functions that will end up in the compiler output.
/// If this method returns false, the compilation will stop.
#[logfn(TRACE)]
fn after_analysis(&mut self, compiler: &interface::Compiler) -> Compilation {
fn after_analysis(&mut self, compiler: &interface::Compiler) -> bool {
compiler.session().abort_if_errors();
if self
.output_directory
Expand All @@ -101,20 +100,15 @@ impl rustc_driver::Callbacks for MiraiCallbacks {
.contains("/build/")
{
// No need to analyze a build script, but do generate code.
return Compilation::Continue;
return true;
}
compiler
.global_ctxt()
.unwrap()
.peek_mut()
.enter(|tcx| self.analyze_with_mirai(compiler, &tcx));
if self.test_run {
// We avoid code gen for test cases because LLVM is not used in a thread safe manner.
Compilation::Stop
} else {
// Although MIRAI is only a checker, cargo still needs code generation to work.
Compilation::Continue
}
!self.test_run // Although MIRAI is only a checker, cargo still needs code generation to work.
// We avoid code gen for test cases because LLVM is not used in a thread safe manner.
}
}

Expand Down
2 changes: 1 addition & 1 deletion checker/src/summaries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ impl<'a, 'tcx: 'a> PersistentSummaryCache<'a, 'tcx> {
let summary =
Self::get_persistent_summary_for_db(db, &func_ref.summary_cache_key);
if !def_id.is_local() && summary.is_none() {
info!(
warn!(
"Summary store has no entry for {}{}",
&func_ref.summary_cache_key, &func_ref.argument_type_key
);
Expand Down
183 changes: 69 additions & 114 deletions checker/src/visitors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2032,7 +2032,7 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
}
// If we always get here if called, give an error.
if entry_cond_as_bool.is_some() && entry_cond_as_bool.unwrap() {
let error = get_assert_msg_description(msg);
let error = msg.description();
let span = self.current_span;
// For now emit a warning since path conditions are not properly widened
// during loops and thus may result in false negatives.
Expand All @@ -2051,7 +2051,7 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
// We expect public functions to have programmer supplied preconditions
// that preclude any assertions from failing. So, if at this stage we get to
// complain a bit.
let warning = format!("possible {}", get_assert_msg_description(msg));
let warning = format!("possible {}", msg.description());
let span = self.current_span;
let warning = self.session.struct_span_warn(span, warning.as_str());
self.emit_diagnostic(warning);
Expand All @@ -2075,7 +2075,7 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
.entry_condition
.logical_not()
.or(expected_cond);
let message = Rc::new(String::from(get_assert_msg_description(msg)));
let message = Rc::new(String::from(msg.description()));
let precondition = Precondition {
condition,
message,
Expand All @@ -2086,14 +2086,6 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
}
}
};

fn get_assert_msg_description<'tcx>(msg: &mir::AssertMessage<'tcx>) -> &'tcx str {
match msg {
mir::interpret::PanicInfo::BoundsCheck { .. } => "index out of bounds",
mir::interpret::PanicInfo::Panic { .. } => "panic",
_ => msg.description(),
}
}
}

/// Checks the given condition value and also checks if the current entry condition can be true.
Expand Down Expand Up @@ -3034,9 +3026,6 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
};
Rc::new(result.clone().into())
}
} else {
debug!("unsupported array length: {:?}", length);
unimplemented!();
}
}

Expand Down Expand Up @@ -3182,11 +3171,11 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
/// can be serialized and used as a cache key.
#[logfn_inputs(TRACE)]
fn visit_place(&mut self, place: &mir::Place<'tcx>) -> Rc<Path> {
let base_path = match &place.base {
mir::PlaceBase::Local(local) => {
let ordinal = local.as_usize();
let result: Rc<Path> = Path::new_local(ordinal);
if place.projection.is_none() {
match place {
mir::Place::Base(base_place) => match base_place {
mir::PlaceBase::Local(local) => {
let ordinal = local.as_usize();
let result: Rc<Path> = Path::new_local(ordinal);
let ty = self.get_rustc_place_type(place);
match &ty.sty {
TyKind::Array(_, len) => {
Expand All @@ -3209,47 +3198,32 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
}
_ => (),
}
result
}
result
}
mir::PlaceBase::Static(boxed_static) => match boxed_static.kind {
mir::StaticKind::Promoted(promoted) => {
let index = promoted.index();
Rc::new(PathEnum::PromotedConstant { ordinal: index }.into())
}
mir::StaticKind::Static(def_id) => {
let name = utils::summary_key_str(&self.tcx, def_id);
Rc::new(
PathEnum::StaticVariable {
def_id: Some(def_id),
summary_cache_key: name,
expression_type: self.get_place_type(place),
}
.into(),
)
}
mir::PlaceBase::Static(boxed_static) => match boxed_static.kind {
mir::StaticKind::Promoted(promoted) => {
let index = promoted.index();
Rc::new(PathEnum::PromotedConstant { ordinal: index }.into())
}
mir::StaticKind::Static(def_id) => {
let name = utils::summary_key_str(&self.tcx, def_id);
Rc::new(
PathEnum::StaticVariable {
def_id: Some(def_id),
summary_cache_key: name,
expression_type: self.get_place_type(place),
}
.into(),
)
}
},
},
};
if let Some(boxed_projection) = &place.projection {
self.visit_projection(base_path, &boxed_projection)
} else {
base_path
}
}

/// Returns a path that is qualified by the selector corresponding to projection.elem.
/// If projection has a base, the give base_path is first qualified with the base.
#[logfn_inputs(TRACE)]
fn visit_projection(
&mut self,
mut base_path: Rc<Path>,
projection: &mir::Projection<'tcx>,
) -> Rc<Path> {
if let Some(boxed_projection) = &projection.base {
base_path = self.visit_projection(base_path, &boxed_projection);
mir::Place::Projection(boxed_place_projection) => {
let base = self.visit_place(&boxed_place_projection.base);
let selector = self.visit_projection_elem(&boxed_place_projection.elem);
Path::new_qualified(base, Rc::new(selector)).refine_paths(&self.current_environment)
}
}
let selector = self.visit_projection_elem(&projection.elem);
Path::new_qualified(base_path, Rc::new(selector)).refine_paths(&self.current_environment)
}

/// Returns a PathSelector instance that is essentially the same as the ProjectionElem instance
Expand Down Expand Up @@ -3301,17 +3275,16 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
/// Returns the rustc TyKind of the given place in memory.
#[logfn_inputs(TRACE)]
fn get_rustc_place_type(&self, place: &mir::Place<'tcx>) -> Ty<'tcx> {
let base_type = match &place.base {
mir::PlaceBase::Local(local) => {
self.mir.local_decls[mir::Local::from(local.as_usize())].ty
}
mir::PlaceBase::Static(boxed_static) => boxed_static.ty,
};
match &place.projection {
Some(boxed_projection) => {
self.get_type_for_projection_element(base_type, boxed_projection)
match place {
mir::Place::Base(base_place) => match base_place {
mir::PlaceBase::Local(local) => {
self.mir.local_decls[mir::Local::from(local.as_usize())].ty
}
mir::PlaceBase::Static(boxed_static) => boxed_static.ty,
},
mir::Place::Projection(_boxed_place_projection) => {
self.get_type_for_projection_element(place)
}
None => base_type,
}
}

Expand Down Expand Up @@ -3358,55 +3331,37 @@ impl<'a, 'b: 'a, 'tcx: 'b, E> MirVisitor<'a, 'b, 'tcx, E> {
}
}

/// Returns the element type of an array or slice type.
fn get_element_type(ty: Ty<'tcx>) -> Ty<'tcx> {
match &ty.sty {
TyKind::Array(t, _) => *t,
TyKind::Slice(t) => *t,
_ => ty,
}
}

/// Returns the rustc TyKind of the element selected by projection_elem.
#[logfn_inputs(TRACE)]
fn get_type_for_projection_element(
&self,
mut base_ty: Ty<'tcx>,
boxed_place_projection: &rustc::mir::Projection<'tcx>,
) -> Ty<'tcx> {
if let Some(boxed_base_projection) = &boxed_place_projection.base {
base_ty = self.get_type_for_projection_element(base_ty, &boxed_base_projection);
};
match boxed_place_projection.elem {
mir::ProjectionElem::Deref => match &base_ty.sty {
TyKind::Adt(..) => base_ty,
TyKind::RawPtr(ty_and_mut) => ty_and_mut.ty,
TyKind::Ref(_, ty, _) => *ty,
_ => {
debug!(
"span: {:?}\nelem: {:?} type: {:?}",
self.current_span, boxed_place_projection.elem, base_ty
);
assume_unreachable!();
}
},
mir::ProjectionElem::Field(_, ty) => ty,
mir::ProjectionElem::Index(_)
| mir::ProjectionElem::ConstantIndex { .. }
| mir::ProjectionElem::Subslice { .. } => match &base_ty.sty {
TyKind::Adt(..) => base_ty,
TyKind::Array(ty, _) => *ty,
TyKind::Ref(_, ty, _) => Self::get_element_type(*ty),
TyKind::Slice(ty) => *ty,
_ => {
debug!(
"span: {:?}\nelem: {:?} type: {:?}",
self.current_span, boxed_place_projection.elem, base_ty
);
assume_unreachable!();
}
},
mir::ProjectionElem::Downcast(..) => base_ty,
fn get_type_for_projection_element(&self, place: &mir::Place<'tcx>) -> Ty<'tcx> {
if let mir::Place::Projection(boxed_place_projection) = place {
let base_ty = self.get_rustc_place_type(&boxed_place_projection.base);
match boxed_place_projection.elem {
mir::ProjectionElem::Deref => match &base_ty.sty {
TyKind::Adt(..) => base_ty,
TyKind::RawPtr(ty_and_mut) => ty_and_mut.ty,
TyKind::Ref(_, ty, _) => *ty,
_ => unreachable!(
"span: {:?}\nelem: {:?}",
self.current_span, boxed_place_projection.elem
),
},
mir::ProjectionElem::Field(_, ty) => ty,
mir::ProjectionElem::Index(_)
| mir::ProjectionElem::ConstantIndex { .. }
| mir::ProjectionElem::Subslice { .. } => match &base_ty.sty {
TyKind::Adt(..) => base_ty,
TyKind::Array(ty, _) => ty,
TyKind::Slice(ty) => ty,
_ => unreachable!(
"span: {:?}\nelem: {:?}",
self.current_span, boxed_place_projection.elem
),
},
mir::ProjectionElem::Downcast(..) => base_ty,
}
} else {
unreachable!("span: {:?}\nplace: {:?}", self.current_span, place)
}
}
}
2 changes: 1 addition & 1 deletion checker/tests/run-pass/array_access_with_unwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// A test that needs to do cleanup if an array access is out of bounds.

pub fn foo(arr: &mut [i32], i: usize) -> String {
arr[i] = 123; //~ possible index out of bounds
arr[i] = 123; //~ possible array index out of bounds
let result = String::from("foo");
let _e = arr[i]; // no warning here because we can't get here unless line 10 succeeded
result
Expand Down
2 changes: 1 addition & 1 deletion checker/tests/run-pass/array_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
extern crate mirai_annotations;

pub fn foo(arr: &mut [i32], i: usize) {
arr[i] = 123; //~ possible index out of bounds
arr[i] = 123; //~ possible array index out of bounds
// If we get here i is known to be within bounds, so no warning below.
bar(arr, i);
}
Expand Down
4 changes: 2 additions & 2 deletions checker/tests/run-pass/array_literal_out_of_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

pub fn main() {
let x = [1, 2];
let _y = x[2]; //~ index out of bounds
let _y = x[2]; //~ array index out of bounds
}

pub fn foo(c: bool) {
Expand All @@ -20,5 +20,5 @@ pub fn foo(c: bool) {
pub fn bar(c: bool) {
let x = [1, 2];
let i = if c { 1 } else { 2 };
let _y = x[i]; //~ possible index out of bounds
let _y = x[i]; //~ possible array index out of bounds
}
2 changes: 2 additions & 0 deletions checker/tests/run-pass/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

// A test that adds a precondition to an async function

#![feature(async_await)]

#[macro_use]
extern crate mirai_annotations;

Expand Down
2 changes: 1 addition & 1 deletion checker/tests/run-pass/crate_traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ fn test10() {
}

fn test11(arr: &[String]) {
let e = &arr[1]; //~ possible index out of bounds
let e = &arr[1]; //~ possible array index out of bounds
}

fn test12() {
Expand Down
2 changes: 1 addition & 1 deletion checker/tests/run-pass/inferred_precondition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

pub fn main() {
let mut a = [1, 2];
foo(&mut a, 3); //~ index out of bounds
foo(&mut a, 3); //~ array index out of bounds
}

fn foo(arr: &mut [i32], i: usize) {
Expand Down
4 changes: 2 additions & 2 deletions checker/tests/run-pass/subslice_pattern_copy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ pub fn main() {
pub fn subslice_pattern(from_start: bool) {
let a = [[10], [20], [30]];
if from_start {
let [x @ .., _] = a;
let [x.., _] = a;
verify!(x[0][0] == 10);
verify!(x[1][0] == 20);
} else {
let [_, y @ ..] = a;
let [_, y..] = a;
verify!(y[0][0] == 20);
verify!(y[1][0] == 30);
}
Expand Down
4 changes: 2 additions & 2 deletions checker/tests/run-pass/subslice_pattern_move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ struct Foo {
pub fn subslice_pattern(from_start: bool) {
let a = [Foo { f: 10 }, Foo { f: 20 }, Foo { f: 30 }];
if from_start {
let [x @ .., _] = a;
let [x.., _] = a;
verify!(x[0].f == 10);
verify!(x[1].f == 20);
} else {
let [_, y @ ..] = a;
let [_, y..] = a;
verify!(y[0].f == 20);
verify!(y[1].f == 30);
}
Expand Down
Loading

0 comments on commit ef1fb94

Please sign in to comment.