diff options
| author | Ralf Jung <post@ralfj.de> | 2017-08-04 16:01:46 -0700 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2017-08-04 16:02:16 -0700 |
| commit | fb2ed457c6bdbe587e2ac21c2f671d3e30bab353 (patch) | |
| tree | 530e47f37d49ed7791926f80cb6ede5b7227f876 /src | |
| parent | 4957031e3cf2333ae5c5519ffd03237eb4ca426c (diff) | |
| download | rust-fb2ed457c6bdbe587e2ac21c2f671d3e30bab353.tar.gz rust-fb2ed457c6bdbe587e2ac21c2f671d3e30bab353.zip | |
consolidate making Undef release a NOP in one place
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_mir/interpret/validation.rs | 17 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/value.rs | 2 |
2 files changed, 10 insertions, 9 deletions
diff --git a/src/librustc_mir/interpret/validation.rs b/src/librustc_mir/interpret/validation.rs index 5b7c932efc2..f77c7d65ff7 100644 --- a/src/librustc_mir/interpret/validation.rs +++ b/src/librustc_mir/interpret/validation.rs @@ -11,7 +11,7 @@ use super::{ EvalError, EvalResult, EvalErrorKind, EvalContext, DynamicLifetime, AccessKind, LockInfo, - PrimVal, Value, + Value, Lvalue, LvalueExtra, Machine, }; @@ -156,10 +156,11 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { fn validate(&mut self, query: ValidationQuery<'tcx>, mode: ValidationMode) -> EvalResult<'tcx> { match self.try_validate(query, mode) { - // HACK: If, during releasing, we hit memory we cannot use, we just ignore that. - // This can happen because releases are added before drop elaboration. - // TODO: Fix the MIR so that these releases do not happen. - res @ Err(EvalError{ kind: EvalErrorKind::DanglingPointerDeref, ..}) | + // Releasing an uninitalized variable is a NOP. This is needed because + // we have to release the return value of a function; due to destination-passing-style + // the callee may directly write there. + // TODO: Ideally we would know whether the destination is already initialized, and only + // release if it is. res @ Err(EvalError{ kind: EvalErrorKind::ReadUndefBytes, ..}) => { if let ValidationMode::Release = mode { return Ok(()); @@ -187,16 +188,14 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> { } } - // Release of an Undef local is fine, and a NOP. // HACK: For now, bail out if we hit a dead local during recovery (can happen because sometimes we have - // StorageDead before EndRegion). + // StorageDead before EndRegion due to https://github.com/rust-lang/rust/issues/43481). // TODO: We should rather fix the MIR. match query.lval { Lvalue::Local { frame, local } => { let res = self.stack[frame].get_local(local); match (res, mode) { - (Err(EvalError{ kind: EvalErrorKind::DeadLocal, ..}), ValidationMode::Recover(_)) | - (Ok(Value::ByVal(PrimVal::Undef)), ValidationMode::Release) => { + (Err(EvalError{ kind: EvalErrorKind::DeadLocal, ..}), ValidationMode::Recover(_)) => { return Ok(()); } _ => {}, diff --git a/src/librustc_mir/interpret/value.rs b/src/librustc_mir/interpret/value.rs index 163643be01c..88ffc57a8f0 100644 --- a/src/librustc_mir/interpret/value.rs +++ b/src/librustc_mir/interpret/value.rs @@ -197,6 +197,7 @@ impl<'a, 'tcx: 'a> Value { ByValPair(ptr, vtable) => Ok((ptr.into(), vtable.to_ptr()?)), + ByVal(PrimVal::Undef) => err!(ReadUndefBytes), _ => bug!("expected ptr and vtable, got {:?}", self), } } @@ -216,6 +217,7 @@ impl<'a, 'tcx: 'a> Value { assert_eq!(len as u64 as u128, len); Ok((ptr.into(), len as u64)) }, + ByVal(PrimVal::Undef) => err!(ReadUndefBytes), ByVal(_) => bug!("expected ptr and length, got {:?}", self), } } |
