prevent more deallocations of statics

This commit is contained in:
Oliver Schneider 2017-02-08 15:32:49 +01:00
parent fbfd2d4bca
commit 3db6ec3f11
3 changed files with 30 additions and 1 deletions

View File

@ -329,6 +329,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}
},
}
// see comment on `initialized` field
assert!(!global_value.initialized);
global_value.initialized = true;
assert!(global_value.mutable);
global_value.mutable = mutable;
} else {
@ -868,7 +871,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
_ => {
let ptr = self.alloc_ptr_with_substs(global_val.ty, cid.substs)?;
self.write_value_to_ptr(global_val.value, ptr, global_val.ty)?;
self.memory.mark_static(ptr.alloc_id, global_val.mutable)?;
// see comment on `initialized` field
if global_val.initialized {
self.memory.mark_static(ptr.alloc_id, global_val.mutable)?;
}
let lval = self.globals.get_mut(&cid).expect("already checked");
*lval = Global {
value: Value::ByRef(ptr),

View File

@ -57,6 +57,11 @@ pub struct GlobalId<'tcx> {
#[derive(Copy, Clone, Debug)]
pub struct Global<'tcx> {
pub(super) value: Value,
/// Only used in `force_allocation` to ensure we don't mark the memory
/// before the static is initialized. It is possible to convert a
/// global which initially is `Value::ByVal(PrimVal::Undef)` and gets
/// lifted to an allocation before the static is fully initialized
pub(super) initialized: bool,
pub(super) mutable: bool,
pub(super) ty: Ty<'tcx>,
}
@ -102,6 +107,7 @@ impl<'tcx> Global<'tcx> {
value: Value::ByVal(PrimVal::Undef),
mutable: true,
ty,
initialized: false,
}
}
}

View File

@ -0,0 +1,17 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
struct T (&'static [isize]);
static t : T = T (&[5, 4, 3]);
pub fn main () {
let T(ref v) = t;
assert_eq!(v[0], 5);
}