Skip to content

Commit

Permalink
must: static
Browse files Browse the repository at this point in the history
  • Loading branch information
Medowhill committed May 24, 2024
1 parent 6a636d8 commit 89d79c9
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
27 changes: 27 additions & 0 deletions src/must_analysis/domains.rs
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ impl Node {
pub struct Graph {
pub nodes: Vec<Node>,
locals: HashMap<Local, NodeId>,
statics: HashMap<LocalDefId, NodeId>,
ints: HashMap<u128, AbsLoc>,
}

Expand Down Expand Up @@ -633,6 +634,14 @@ impl Graph {
ctx.remaining.push(idp);
}

for (s1, id1) in &self.statics {
let (_, id2) = some_or!(other.statics.iter().find(|(s2, _)| s1 == *s2), continue);
let id = ctx.joined.get_static(*s1);
let idp = (AbsLoc::new_root(*id1), AbsLoc::new_root(*id2));
ctx.id_map.insert(idp.clone(), id);
ctx.remaining.push(idp);
}

while let Some((loc1, loc2)) = ctx.remaining.pop() {
let obj1 = self.obj_at_location(&loc1);
let obj2 = other.obj_at_location(&loc2);
Expand Down Expand Up @@ -704,6 +713,7 @@ impl Graph {
pub fn assign(&mut self, l: &AccPath, l_deref: bool, r: &OpVal) {
match r {
OpVal::Place(r, r_deref) => self.x_eq_y(l, l_deref, r, *r_deref),
OpVal::Static(s) => self.x_eq_static(l, l_deref, *s),
OpVal::Int(n) => self.x_eq_int(l, l_deref, *n),
OpVal::Other => self.x_eq(l, l_deref),
}
Expand Down Expand Up @@ -842,6 +852,22 @@ impl Graph {
*obj = Obj::Ptr(loc);
}

fn get_static(&mut self, s: LocalDefId) -> NodeId {
if let Some(id) = self.statics.get(&s) {
*id
} else {
let (id, _) = self.add_node();
self.statics.insert(s, id);
id
}
}

fn x_eq_static(&mut self, x: &AccPath, x_deref: bool, y: LocalDefId) {
let id = self.get_static(y);
let obj = self.lvalue(x, x_deref);
*obj = Obj::Ptr(AbsLoc::new_root(id));
}

fn x_eq_int(&mut self, x: &AccPath, deref: bool, n: u128) {
let loc = self.get_int_node(n);
let obj = self.lvalue(x, deref);
Expand Down Expand Up @@ -890,6 +916,7 @@ impl Graph {
let obj = self.lvalue(x, false);
*obj = Obj::Ptr(loc);
}
OpVal::Static(_) => unreachable!(),
OpVal::Int(idx) => {
*n += idx;
let obj = self.lvalue(x, false);
Expand Down
17 changes: 15 additions & 2 deletions src/must_analysis/semantics.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_middle::{
mir::{
interpret::{ConstValue, Scalar},
interpret::{ConstValue, GlobalAlloc, Scalar},
AggregateKind, BinOp, CastKind, ConstantKind, HasLocalDecls, Local, Location, Operand,
Place, PlaceElem, ProjectionElem, Rvalue, Statement, StatementKind, Terminator,
TerminatorKind, UnOp,
Expand Down Expand Up @@ -267,7 +267,17 @@ impl<'tcx> Analyzer<'tcx, '_, '_> {
}
_ => OpVal::Other,
},
Scalar::Ptr(_, _) => OpVal::Other,
Scalar::Ptr(ptr, _) => match self.tcx.global_alloc(ptr.provenance) {
GlobalAlloc::Static(def_id) => {
if let Some(def_id) = def_id.as_local() {
OpVal::Static(def_id)
} else {
OpVal::Other
}
}
GlobalAlloc::Memory(_) => OpVal::Other,
_ => unreachable!(),
},
},
ConstValue::ZeroSized => OpVal::Other,
ConstValue::Slice { .. } => unreachable!(),
Expand Down Expand Up @@ -367,6 +377,7 @@ impl<'tcx> Analyzer<'tcx, '_, '_> {
.collect()
}
},
OpVal::Static(_) => unreachable!(),
OpVal::Int(i) => {
let target_opt = targets.iter().find(|(v, _)| i == *v);
let target = if let Some((_, target)) = target_opt {
Expand Down Expand Up @@ -601,6 +612,7 @@ impl<'tcx> Analyzer<'tcx, '_, '_> {
#[derive(Debug, Clone)]
pub enum OpVal {
Place(AccPath, bool),
Static(LocalDefId),
Int(u128),
Other,
}
Expand All @@ -617,6 +629,7 @@ impl OpVal {
fn extend_projection(&mut self, proj: &[AccElem]) {
match self {
OpVal::Place(path, _) => path.extend_projection(proj),
OpVal::Static(_) => unreachable!(),
OpVal::Int(_) => assert!(proj.is_empty()),
OpVal::Other => {}
}
Expand Down
53 changes: 53 additions & 0 deletions src/must_analysis/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2220,3 +2220,56 @@ fn test_union_field_invalidate() {
},
);
}

#[test]
fn test_eq_static() {
// _1 = const 1_i32
// _2 = const {alloc1: *mut i32}
// (*_2) = move _1
// _4 = const {alloc1: *mut i32}
// _3 = (*_4)
analyze_fn_with(
"
pub static mut x: libc::c_int = 0 as libc::c_int;
",
"",
"
x = 1 as libc::c_int;
let mut y: libc::c_int = x;
",
|g, _, _| {
let n = get_nodes(&g, 1..=4);
assert_eq!(n[&1].as_ptr(), n[&3].as_ptr());
assert_eq!(n[&2].as_ptr(), n[&4].as_ptr());
},
);
}

#[test]
fn test_static_invalidate() {
// _1 = const 1_i32
// _2 = const {alloc1: *mut i32}
// (*_2) = move _1
// _3 = g() -> [return: bb1, unwind continue]
// _5 = const {alloc1: *mut i32}
// _4 = (*_5)
analyze_fn_with(
"
pub static mut x: libc::c_int = 0 as libc::c_int;
pub unsafe extern \"C\" fn g() {
x = 2 as libc::c_int;
}
",
"",
"
x = 1 as libc::c_int;
g();
let mut y: libc::c_int = x;
",
|g, _, _| {
let n = get_nodes(&g, 1..=5);
assert_ne!(n[&1].as_ptr(), n[&4].as_ptr());
assert_eq!(n[&2].as_ptr(), n[&5].as_ptr());
},
);
}

0 comments on commit 89d79c9

Please sign in to comment.