From ef1fb9446840384b54a4f04963836a406cf54fec Mon Sep 17 00:00:00 2001 From: Herman Venter Date: Thu, 15 Aug 2019 20:29:52 -0700 Subject: [PATCH] Roll back to nightly-2019-07-08 for release to LIBRA --- .travis.yml | 2 +- checker/src/callbacks.rs | 14 +- checker/src/summaries.rs | 2 +- checker/src/visitors.rs | 183 +++++++----------- .../run-pass/array_access_with_unwind.rs | 2 +- checker/tests/run-pass/array_index.rs | 2 +- .../run-pass/array_literal_out_of_bounds.rs | 4 +- checker/tests/run-pass/async.rs | 2 + checker/tests/run-pass/crate_traversal.rs | 2 +- .../tests/run-pass/inferred_precondition.rs | 2 +- .../tests/run-pass/subslice_pattern_copy.rs | 4 +- .../tests/run-pass/subslice_pattern_move.rs | 4 +- rust-toolchain | 2 +- 13 files changed, 88 insertions(+), 137 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3c1291b6..84885b81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/checker/src/callbacks.rs b/checker/src/callbacks.rs index d7339ad7..03ac30d4 100644 --- a/checker/src/callbacks.rs +++ b/checker/src/callbacks.rs @@ -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}; @@ -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 @@ -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. } } diff --git a/checker/src/summaries.rs b/checker/src/summaries.rs index 4ff5ab05..b0f3e0d3 100644 --- a/checker/src/summaries.rs +++ b/checker/src/summaries.rs @@ -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 ); diff --git a/checker/src/visitors.rs b/checker/src/visitors.rs index b8dbd84d..aa70bf26 100644 --- a/checker/src/visitors.rs +++ b/checker/src/visitors.rs @@ -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. @@ -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); @@ -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, @@ -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. @@ -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!(); } } @@ -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 { - let base_path = match &place.base { - mir::PlaceBase::Local(local) => { - let ordinal = local.as_usize(); - let result: Rc = 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::new_local(ordinal); let ty = self.get_rustc_place_type(place); match &ty.sty { TyKind::Array(_, len) => { @@ -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, - projection: &mir::Projection<'tcx>, - ) -> Rc { - 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 @@ -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, } } @@ -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) } } } diff --git a/checker/tests/run-pass/array_access_with_unwind.rs b/checker/tests/run-pass/array_access_with_unwind.rs index 1404e6a4..9553ffc0 100644 --- a/checker/tests/run-pass/array_access_with_unwind.rs +++ b/checker/tests/run-pass/array_access_with_unwind.rs @@ -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 diff --git a/checker/tests/run-pass/array_index.rs b/checker/tests/run-pass/array_index.rs index f3aa8c7f..8ce2a8c3 100644 --- a/checker/tests/run-pass/array_index.rs +++ b/checker/tests/run-pass/array_index.rs @@ -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); } diff --git a/checker/tests/run-pass/array_literal_out_of_bounds.rs b/checker/tests/run-pass/array_literal_out_of_bounds.rs index dfa85c22..76d9b285 100644 --- a/checker/tests/run-pass/array_literal_out_of_bounds.rs +++ b/checker/tests/run-pass/array_literal_out_of_bounds.rs @@ -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) { @@ -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 } diff --git a/checker/tests/run-pass/async.rs b/checker/tests/run-pass/async.rs index 75475c94..78aab480 100644 --- a/checker/tests/run-pass/async.rs +++ b/checker/tests/run-pass/async.rs @@ -6,6 +6,8 @@ // A test that adds a precondition to an async function +#![feature(async_await)] + #[macro_use] extern crate mirai_annotations; diff --git a/checker/tests/run-pass/crate_traversal.rs b/checker/tests/run-pass/crate_traversal.rs index 5baef467..171d2fda 100644 --- a/checker/tests/run-pass/crate_traversal.rs +++ b/checker/tests/run-pass/crate_traversal.rs @@ -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() { diff --git a/checker/tests/run-pass/inferred_precondition.rs b/checker/tests/run-pass/inferred_precondition.rs index 16b5f613..8d25c974 100644 --- a/checker/tests/run-pass/inferred_precondition.rs +++ b/checker/tests/run-pass/inferred_precondition.rs @@ -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) { diff --git a/checker/tests/run-pass/subslice_pattern_copy.rs b/checker/tests/run-pass/subslice_pattern_copy.rs index c6ad26ab..7e904dc4 100644 --- a/checker/tests/run-pass/subslice_pattern_copy.rs +++ b/checker/tests/run-pass/subslice_pattern_copy.rs @@ -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); } diff --git a/checker/tests/run-pass/subslice_pattern_move.rs b/checker/tests/run-pass/subslice_pattern_move.rs index 8f458719..677cf39b 100644 --- a/checker/tests/run-pass/subslice_pattern_move.rs +++ b/checker/tests/run-pass/subslice_pattern_move.rs @@ -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); } diff --git a/rust-toolchain b/rust-toolchain index 3ee76a49..b7838311 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly-2019-08-27 +nightly-2019-07-08