fetch_tls_dtor "read" an Undef as nonzero

This commit is contained in:
Oliver Schneider 2017-06-23 13:31:00 +02:00
parent c4fc6c677d
commit 5ee4fdcd15
2 changed files with 9 additions and 5 deletions

View file

@ -362,7 +362,11 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
StackPopCleanup::None => {},
StackPopCleanup::Tls(key) => {
// either fetch the next dtor or start new from the beginning, if any are left with a non-null data
if let Some((instance, ptr, key)) = self.memory.fetch_tls_dtor(key).or_else(|| self.memory.fetch_tls_dtor(None)) {
let dtor = match self.memory.fetch_tls_dtor(key)? {
dtor @ Some(_) => dtor,
None => self.memory.fetch_tls_dtor(None)?,
};
if let Some((instance, ptr, key)) = dtor {
trace!("Running TLS dtor {:?} on {:?}", instance, ptr);
// TODO: Potentially, this has to support all the other possible instances? See eval_fn_call in terminator/mod.rs
let mir = self.load_mir(instance.def)?;

View file

@ -404,22 +404,22 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
/// with associated destructors, implementations may stop calling destructors,
/// or they may continue calling destructors until no non-NULL values with
/// associated destructors exist, even though this might result in an infinite loop.
pub(crate) fn fetch_tls_dtor(&mut self, key: Option<TlsKey>) -> Option<(ty::Instance<'tcx>, PrimVal, TlsKey)> {
pub(crate) fn fetch_tls_dtor(&mut self, key: Option<TlsKey>) -> EvalResult<'tcx, Option<(ty::Instance<'tcx>, PrimVal, TlsKey)>> {
use std::collections::Bound::*;
let start = match key {
Some(key) => Excluded(key),
None => Unbounded,
};
for (&key, &mut TlsEntry { ref mut data, dtor }) in self.thread_local.range_mut((start, Unbounded)) {
if *data != PrimVal::Bytes(0) {
if !data.is_null()? {
if let Some(dtor) = dtor {
let ret = Some((dtor, *data, key));
*data = PrimVal::Bytes(0);
return ret;
return Ok(ret);
}
}
}
return None;
return Ok(None);
}
}