From df10965dc019fdbea1a302ed1a0a8fb358f3c388 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 8 Nov 2018 20:15:13 +0100 Subject: [PATCH 1/3] Prevent ICE in const-prop array oob check --- src/librustc_mir/transform/const_prop.rs | 16 ++++++++-------- src/test/ui/consts/const-prop-ice.rs | 3 +++ src/test/ui/consts/const-prop-ice.stderr | 10 ++++++++++ 3 files changed, 21 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/consts/const-prop-ice.rs create mode 100644 src/test/ui/consts/const-prop-ice.stderr diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 4f92ba400481b..885d70dc4304d 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -591,8 +591,8 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { if let TerminatorKind::Assert { expected, msg, cond, .. } = kind { if let Some(value) = self.eval_operand(cond, source_info) { trace!("assertion on {:?} should be {:?}", value, expected); - let expected = Immediate::Scalar(Scalar::from_bool(*expected).into()); - if expected != value.0.to_immediate() { + let expected = ScalarMaybeUndef::from(Scalar::from_bool(*expected)); + if expected != self.ecx.read_scalar(value.0).unwrap() { // poison all places this operand references so that further code // doesn't use the invalid value match cond { @@ -628,20 +628,20 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> { let len = self .eval_operand(len, source_info) .expect("len must be const"); - let len = match len.0.to_immediate() { - Immediate::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits { + let len = match self.ecx.read_scalar(len.0) { + Ok(ScalarMaybeUndef::Scalar(Scalar::Bits { bits, .. })) => bits, - _ => bug!("const len not primitive: {:?}", len), + other => bug!("const len not primitive: {:?}", other), }; let index = self .eval_operand(index, source_info) .expect("index must be const"); - let index = match index.0.to_immediate() { - Immediate::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits { + let index = match self.ecx.read_scalar(index.0) { + Ok(ScalarMaybeUndef::Scalar(Scalar::Bits { bits, .. })) => bits, - _ => bug!("const index not primitive: {:?}", index), + other => bug!("const index not primitive: {:?}", other), }; format!( "index out of bounds: \ diff --git a/src/test/ui/consts/const-prop-ice.rs b/src/test/ui/consts/const-prop-ice.rs new file mode 100644 index 0000000000000..17880adc7af2f --- /dev/null +++ b/src/test/ui/consts/const-prop-ice.rs @@ -0,0 +1,3 @@ +fn main() { + [0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3 +} \ No newline at end of file diff --git a/src/test/ui/consts/const-prop-ice.stderr b/src/test/ui/consts/const-prop-ice.stderr new file mode 100644 index 0000000000000..749ef952b5ddb --- /dev/null +++ b/src/test/ui/consts/const-prop-ice.stderr @@ -0,0 +1,10 @@ +error: index out of bounds: the len is 3 but the index is 3 + --> $DIR/const-prop-ice.rs:2:5 + | +LL | [0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3 + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(const_err)] on by default + +error: aborting due to previous error + From ffa7ce42901b7206f06de735986a6e009e6c1c5b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 8 Nov 2018 20:18:26 +0100 Subject: [PATCH 2/3] Add more regression tests --- src/test/ui/consts/const-prop-ice2.rs | 5 +++++ src/test/ui/consts/const-prop-ice2.stderr | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/test/ui/consts/const-prop-ice2.rs create mode 100644 src/test/ui/consts/const-prop-ice2.stderr diff --git a/src/test/ui/consts/const-prop-ice2.rs b/src/test/ui/consts/const-prop-ice2.rs new file mode 100644 index 0000000000000..23bdda2cba728 --- /dev/null +++ b/src/test/ui/consts/const-prop-ice2.rs @@ -0,0 +1,5 @@ +fn main() { + enum Enum { One=1 } + let xs=[0;1 as usize]; + println!("{}", xs[Enum::One as usize]); //~ ERROR the len is 1 but the index is 1 +} \ No newline at end of file diff --git a/src/test/ui/consts/const-prop-ice2.stderr b/src/test/ui/consts/const-prop-ice2.stderr new file mode 100644 index 0000000000000..4febd0ee1e391 --- /dev/null +++ b/src/test/ui/consts/const-prop-ice2.stderr @@ -0,0 +1,10 @@ +error: index out of bounds: the len is 1 but the index is 1 + --> $DIR/const-prop-ice2.rs:4:20 + | +LL | println!("{}", xs[Enum::One as usize]); //~ ERROR the len is 1 but the index is 1 + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[deny(const_err)] on by default + +error: aborting due to previous error + From 1206549d1b3dbdd694b1218516f522e71228b3b5 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 9 Nov 2018 10:11:20 +0100 Subject: [PATCH 3/3] Fix tidy --- src/test/ui/consts/const-prop-ice.rs | 2 +- src/test/ui/consts/const-prop-ice2.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/consts/const-prop-ice.rs b/src/test/ui/consts/const-prop-ice.rs index 17880adc7af2f..13309f978b672 100644 --- a/src/test/ui/consts/const-prop-ice.rs +++ b/src/test/ui/consts/const-prop-ice.rs @@ -1,3 +1,3 @@ fn main() { [0; 3][3u64 as usize]; //~ ERROR the len is 3 but the index is 3 -} \ No newline at end of file +} diff --git a/src/test/ui/consts/const-prop-ice2.rs b/src/test/ui/consts/const-prop-ice2.rs index 23bdda2cba728..e5fd79f11676e 100644 --- a/src/test/ui/consts/const-prop-ice2.rs +++ b/src/test/ui/consts/const-prop-ice2.rs @@ -2,4 +2,4 @@ fn main() { enum Enum { One=1 } let xs=[0;1 as usize]; println!("{}", xs[Enum::One as usize]); //~ ERROR the len is 1 but the index is 1 -} \ No newline at end of file +}