From 3db6ec3f11385c17e5f712cadfb3d31417ac166a Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Wed, 8 Feb 2017 15:32:49 +0100 Subject: [PATCH] prevent more deallocations of statics --- src/eval_context.rs | 8 +++++++- src/lvalue.rs | 6 ++++++ tests/run-pass/issue-5917.rs | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/run-pass/issue-5917.rs diff --git a/src/eval_context.rs b/src/eval_context.rs index 1996bbf9dcb..7ea4003b0f7 100644 --- a/src/eval_context.rs +++ b/src/eval_context.rs @@ -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), diff --git a/src/lvalue.rs b/src/lvalue.rs index df1f166c074..d54c2790476 100644 --- a/src/lvalue.rs +++ b/src/lvalue.rs @@ -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, } } } diff --git a/tests/run-pass/issue-5917.rs b/tests/run-pass/issue-5917.rs new file mode 100644 index 00000000000..112ad0185d8 --- /dev/null +++ b/tests/run-pass/issue-5917.rs @@ -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 or the MIT license +// , 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); +}