Skip to content

Commit 2c836a7

Browse files
committed
Fallout from fixing try_read_value to work with enums
1 parent 551df45 commit 2c836a7

File tree

7 files changed

+35
-56
lines changed

7 files changed

+35
-56
lines changed

src/librustc_mir/interpret/const_eval.rs

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc::hir;
55
use rustc::mir::interpret::{ConstEvalErr, ScalarMaybeUndef};
66
use rustc::mir;
77
use rustc::ty::{self, TyCtxt, Ty, Instance};
8-
use rustc::ty::layout::{self, LayoutOf, Primitive, TyLayout, Size};
8+
use rustc::ty::layout::{self, LayoutOf, Primitive, TyLayout};
99
use rustc::ty::subst::Subst;
1010
use rustc_data_structures::indexed_vec::IndexVec;
1111

@@ -77,46 +77,29 @@ pub fn value_to_const_value<'tcx>(
7777
ecx: &EvalContext<'_, '_, 'tcx, CompileTimeEvaluator>,
7878
val: Value,
7979
layout: TyLayout<'tcx>,
80-
) -> &'tcx ty::Const<'tcx> {
80+
) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> {
8181
match (val, &layout.abi) {
8282
(Value::Scalar(ScalarMaybeUndef::Scalar(Scalar::Bits { size: 0, ..})), _) if layout.is_zst() => {},
8383
(Value::ByRef(..), _) |
8484
(Value::Scalar(_), &layout::Abi::Scalar(_)) |
8585
(Value::ScalarPair(..), &layout::Abi::ScalarPair(..)) => {},
8686
_ => bug!("bad value/layout combo: {:#?}, {:#?}", val, layout),
8787
}
88-
let val = (|| {
89-
match val {
90-
Value::Scalar(val) => Ok(ConstValue::Scalar(val.unwrap_or_err()?)),
91-
Value::ScalarPair(a, b) => Ok(ConstValue::ScalarPair(a.unwrap_or_err()?, b.unwrap_or_err()?)),
92-
Value::ByRef(ptr, align) => {
93-
let ptr = ptr.to_ptr().unwrap();
94-
let alloc = ecx.memory.get(ptr.alloc_id)?;
95-
assert!(alloc.align.abi() >= align.abi());
96-
assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= layout.size.bytes());
97-
let mut alloc = alloc.clone();
98-
alloc.align = align;
99-
let alloc = ecx.tcx.intern_const_alloc(alloc);
100-
Ok(ConstValue::ByRef(alloc, ptr.offset))
101-
}
102-
}
103-
})();
104-
match val {
105-
Ok(val) => ty::Const::from_const_value(ecx.tcx.tcx, val, layout.ty),
106-
Err(error) => {
107-
let (stacktrace, span) = ecx.generate_stacktrace(None);
108-
let err = ConstEvalErr { span, error, stacktrace };
109-
if let Some(mut err) = err.struct_error(ecx.tcx, "failed to convert Value to ConstValue") {
110-
err.delay_as_bug();
111-
} else {
112-
span_bug!(span, "failed to convert Value to ConstValue")
113-
}
114-
let alloc = Allocation::undef(layout.size, layout.align);
88+
let val = match val {
89+
Value::Scalar(val) => ConstValue::Scalar(val.unwrap_or_err()?),
90+
Value::ScalarPair(a, b) => ConstValue::ScalarPair(a.unwrap_or_err()?, b.unwrap_or_err()?),
91+
Value::ByRef(ptr, align) => {
92+
let ptr = ptr.to_ptr().unwrap();
93+
let alloc = ecx.memory.get(ptr.alloc_id)?;
94+
assert!(alloc.align.abi() >= align.abi());
95+
assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= layout.size.bytes());
96+
let mut alloc = alloc.clone();
97+
alloc.align = align;
11598
let alloc = ecx.tcx.intern_const_alloc(alloc);
116-
let val = ConstValue::ByRef(alloc, Size::ZERO);
117-
ty::Const::from_const_value(ecx.tcx.tcx, val, layout.ty)
99+
ConstValue::ByRef(alloc, ptr.offset)
118100
}
119-
}
101+
};
102+
Ok(ty::Const::from_const_value(ecx.tcx.tcx, val, layout.ty))
120103
}
121104

122105
fn eval_body_and_ecx<'a, 'mir, 'tcx>(
@@ -454,7 +437,7 @@ pub fn const_val_field<'a, 'tcx>(
454437
),
455438
_ => {},
456439
}
457-
Ok(value_to_const_value(&ecx, new_value, layout))
440+
value_to_const_value(&ecx, new_value, layout)
458441
})();
459442
result.map_err(|err| {
460443
let (trace, span) = ecx.generate_stacktrace(None);
@@ -555,7 +538,7 @@ pub fn const_eval_provider<'a, 'tcx>(
555538
if tcx.is_static(def_id).is_none() && cid.promoted.is_none() {
556539
val = ecx.try_read_by_ref(val, layout.ty)?;
557540
}
558-
Ok(value_to_const_value(&ecx, val, layout))
541+
value_to_const_value(&ecx, val, layout)
559542
}).map_err(|err| {
560543
let (trace, span) = ecx.generate_stacktrace(None);
561544
let err = ConstEvalErr {

src/test/ui/const-eval/ub-enum-ptr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ union Foo {
2121

2222
// A pointer is guaranteed non-null
2323
const BAD_ENUM: Enum = unsafe { Foo { a: &1 }.b};
24-
//~^ ERROR this constant likely exhibits undefined behavior
24+
//~^ ERROR this constant cannot be used
2525

2626
fn main() {
2727
}
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
error[E0080]: this constant likely exhibits undefined behavior
1+
error: this constant cannot be used
22
--> $DIR/ub-enum-ptr.rs:23:1
33
|
44
LL | const BAD_ENUM: Enum = unsafe { Foo { a: &1 }.b};
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered pointer at .TAG, but expected something in the range 0..=0
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ a raw memory access tried to access part of a pointer value as raw bytes
66
|
7-
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
7+
= note: #[deny(const_err)] on by default
88

99
error: aborting due to previous error
1010

11-
For more information about this error, try `rustc --explain E0080`.

src/test/ui/const-eval/union-const-eval-field.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const fn read_field2() -> Field2 {
3434
}
3535

3636
const fn read_field3() -> Field3 {
37-
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR exhibits undefined behavior
37+
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR cannot be used
3838
FIELD3
3939
}
4040

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
error[E0080]: this constant likely exhibits undefined behavior
1+
error: this constant cannot be used
22
--> $DIR/union-const-eval-field.rs:37:5
33
|
4-
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR exhibits undefined behavior
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered undefined bytes
4+
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR cannot be used
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
66
|
7-
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
7+
= note: #[deny(const_err)] on by default
88

99
error: aborting due to previous error
1010

11-
For more information about this error, try `rustc --explain E0080`.

src/test/ui/const-eval/union-ice.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ union DummyUnion {
2020

2121
const UNION: DummyUnion = DummyUnion { field1: 1065353216 };
2222

23-
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR this constant likely exhibits undefined
23+
const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR this constant cannot be used
2424

25-
const FIELD_PATH: Struct = Struct { //~ ERROR this constant likely exhibits undefined behavior
25+
const FIELD_PATH: Struct = Struct { //~ ERROR this constant cannot be used
2626
a: 42,
2727
b: unsafe { UNION.field3 },
2828
};

src/test/ui/const-eval/union-ice.stderr

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
1-
error[E0080]: this constant likely exhibits undefined behavior
1+
error: this constant cannot be used
22
--> $DIR/union-ice.rs:23:1
33
|
4-
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR this constant likely exhibits undefined
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered undefined bytes
4+
LL | const FIELD3: Field3 = unsafe { UNION.field3 }; //~ ERROR this constant cannot be used
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes
66
|
7-
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
7+
= note: #[deny(const_err)] on by default
88

9-
error[E0080]: this constant likely exhibits undefined behavior
9+
error: this constant cannot be used
1010
--> $DIR/union-ice.rs:25:1
1111
|
12-
LL | / const FIELD_PATH: Struct = Struct { //~ ERROR this constant likely exhibits undefined behavior
12+
LL | / const FIELD_PATH: Struct = Struct { //~ ERROR this constant cannot be used
1313
LL | | a: 42,
1414
LL | | b: unsafe { UNION.field3 },
1515
LL | | };
16-
| |__^ type validation failed: encountered undefined bytes at .b
17-
|
18-
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
16+
| |__^ attempted to read undefined bytes
1917

2018
error[E0080]: this constant likely exhibits undefined behavior
2119
--> $DIR/union-ice.rs:35:1

0 commit comments

Comments
 (0)