From d389f64cdb5b4a99075030131378b52ee791d8be Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 13 Nov 2019 19:19:25 -0500 Subject: [PATCH 1/4] Fix spurious CI filures due to OOM Fixes #66342 --- src/librustc_mir/transform/const_prop.rs | 11 ++++++++--- src/test/ui/consts/issue-66342.rs | 9 +++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/consts/issue-66342.rs diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 2ede43e2111ed..979d109aa05b9 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -22,7 +22,7 @@ use rustc::ty::subst::InternalSubsts; use rustc_data_structures::fx::FxHashMap; use rustc_index::vec::IndexVec; use rustc::ty::layout::{ - LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, + LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size, }; use crate::rustc::ty::subst::Subst; @@ -35,6 +35,9 @@ use crate::interpret::{ use crate::const_eval::error_to_const_error; use crate::transform::{MirPass, MirSource}; +/// The maximum number of bytes that we'll allocate space for a return value. +const MAX_ALLOC_LIMIT: u64 = 1024; + pub struct ConstProp; impl<'tcx> MirPass<'tcx> for ConstProp { @@ -313,8 +316,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ecx .layout_of(body.return_ty().subst(tcx, substs)) .ok() - // Don't bother allocating memory for ZST types which have no values. - .filter(|ret_layout| !ret_layout.is_zst()) + // Don't bother allocating memory for ZST types which have no values + // or for large values. + .filter(|ret_layout| !ret_layout.is_zst() && + ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT)) .map(|ret_layout| ecx.allocate(ret_layout, MemoryKind::Stack)); ecx.push_stack_frame( diff --git a/src/test/ui/consts/issue-66342.rs b/src/test/ui/consts/issue-66342.rs new file mode 100644 index 0000000000000..fa2a6f7567316 --- /dev/null +++ b/src/test/ui/consts/issue-66342.rs @@ -0,0 +1,9 @@ +// check-pass + +fn foo() -> [u8; 4 * 1024 * 1024 * 1024 * 1024] { + unimplemented!() +} + +fn main() { + foo(); +} From 3732b7acf1a9cbe8578f6612057d69b4b5e28e44 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Wed, 13 Nov 2019 20:37:33 -0500 Subject: [PATCH 2/4] [ConstProp] Avoid OOM crashes by not evaluating large Places Fixes #66397 --- src/librustc_mir/transform/const_prop.rs | 5 +++++ src/test/ui/consts/issue-66397.rs | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 src/test/ui/consts/issue-66397.rs diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 979d109aa05b9..51d0ab7943c75 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -458,6 +458,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { ) -> Option<()> { let span = source_info.span; + // #66397: Don't try to eval into large places as that can cause an OOM + if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) { + return None; + } + let overflow_check = self.tcx.sess.overflow_checks(); // Perform any special handling for specific Rvalue types. diff --git a/src/test/ui/consts/issue-66397.rs b/src/test/ui/consts/issue-66397.rs new file mode 100644 index 0000000000000..0830c060e56af --- /dev/null +++ b/src/test/ui/consts/issue-66397.rs @@ -0,0 +1,5 @@ +// build-pass + +fn main() { + [0; 4 * 1024 * 1024 * 1024 * 1024]; +} From 9e1b210c6ae98b2df5362c2d1ced67616105d575 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 14 Nov 2019 06:17:41 -0500 Subject: [PATCH 3/4] Respond to review feedback --- src/test/ui/consts/issue-66342.rs | 2 ++ src/test/ui/consts/issue-66397.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/test/ui/consts/issue-66342.rs b/src/test/ui/consts/issue-66342.rs index fa2a6f7567316..5c93f874256ee 100644 --- a/src/test/ui/consts/issue-66342.rs +++ b/src/test/ui/consts/issue-66342.rs @@ -1,5 +1,7 @@ // check-pass +// Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash. + fn foo() -> [u8; 4 * 1024 * 1024 * 1024 * 1024] { unimplemented!() } diff --git a/src/test/ui/consts/issue-66397.rs b/src/test/ui/consts/issue-66397.rs index 0830c060e56af..b9cf163bc61f8 100644 --- a/src/test/ui/consts/issue-66397.rs +++ b/src/test/ui/consts/issue-66397.rs @@ -1,5 +1,7 @@ // build-pass +// Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash. + fn main() { [0; 4 * 1024 * 1024 * 1024 * 1024]; } From 2dea8af20cf494914d09105eb0c6c8924883f683 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 14 Nov 2019 20:48:42 -0500 Subject: [PATCH 4/4] Only run tests on x86_64 --- src/test/ui/consts/issue-66342.rs | 1 + src/test/ui/consts/issue-66397.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/ui/consts/issue-66342.rs b/src/test/ui/consts/issue-66342.rs index 5c93f874256ee..417f69041658d 100644 --- a/src/test/ui/consts/issue-66342.rs +++ b/src/test/ui/consts/issue-66342.rs @@ -1,4 +1,5 @@ // check-pass +// only-x86_64 // Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash. diff --git a/src/test/ui/consts/issue-66397.rs b/src/test/ui/consts/issue-66397.rs index b9cf163bc61f8..1b4aff43b5bf1 100644 --- a/src/test/ui/consts/issue-66397.rs +++ b/src/test/ui/consts/issue-66397.rs @@ -1,4 +1,5 @@ -// build-pass +// check-pass +// only-x86_64 // Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash.