Skip to content

Commit

Permalink
[WIP] Semantics of immutable arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
JustusAdam committed Jan 19, 2024
1 parent a1ab5c7 commit 0fe3273
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 17 deletions.
43 changes: 26 additions & 17 deletions crates/flowistry/src/pdg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,10 +687,11 @@ impl<'tcx> GraphConstructor<'tcx> {
};
// An attempt at getting immutable arguments to connect
let parentable_srcs = if self.params.false_call_edges {
let dummy_state = PartialGraph::default();
let constructor_ref = &child_constructor;
Either::Right(child_constructor.body.args_iter()
.map(|local| Place::from(local))
.flat_map(|place| child_constructor.place_info.children(place).into_iter().chain([place]))
.map(|place| DepNode::new(place, child_constructor.make_call_string(RichLocation::Start), self.tcx, child_constructor.body.as_ref())))
.flat_map(move |place| constructor_ref.find_data_inputs(&dummy_state, place)))
} else {
Either::Left(child_graph
.edges
Expand Down Expand Up @@ -864,23 +865,24 @@ impl<'tcx> GraphConstructor<'tcx> {
let mut domains = IndexVec::from_elem_n(empty.clone(), bb_graph.len());

if self.params.false_call_edges {
let start_domain = &mut domains[0_usize.into()];
// TODO, actually should traverse all of the types fields
let start_domain = &mut domains[0_u32.into()];
for arg in self.body.args_iter() {
let place = Place::from(arg);
start_domain.last_mutation
.entry(place)
.or_default()
.insert(RichLocation::Start);
for child in self.place_info.children(place).iter().copied().chain(Some(place)) {
let ty = child.ty(self.body.as_ref(), self.tcx);
if !ty.ty.is_mutable_ptr() {
continue;
}
let target = child.project_deeper(&[PlaceElem::Deref], self.tcx);
let initial = start_domain.last_mutation.entry(target).or_default();
initial.insert(RichLocation::Start);
for mutation in self.find_data_inputs(start_domain, place) {
start_domain.last_mutation
.entry(mutation.place)
.or_default()
.insert(RichLocation::Start);
}
// for child in self.place_info.children(place).iter().copied() {
// let ty = child.ty(self.body.as_ref(), self.tcx);
// if !ty.ty.is_mutable_ptr() {
// continue;
// }
// let target = child.project_deeper(&[PlaceElem::Deref], self.tcx);
// let initial = start_domain.last_mutation.entry(target).or_default();
// initial.insert(RichLocation::Start);
// }
}
}

Expand Down Expand Up @@ -910,7 +912,7 @@ impl<'tcx> GraphConstructor<'tcx> {
for block in all_returns {
let return_state = &domains[block];
for (place, locations) in &return_state.last_mutation {
if place.local == RETURN_PLACE || place.is_arg(&self.body) {
if place.local == RETURN_PLACE || self.is_ptr_argument_mutation(*place) {
for location in locations {
let src = self.make_dep_node(*place, *location);
let dst = self.make_dep_node(*place, RichLocation::End);
Expand All @@ -926,6 +928,13 @@ impl<'tcx> GraphConstructor<'tcx> {
final_state
}

fn is_ptr_argument_mutation(&self, place: Place<'tcx>) -> bool {
place.is_arg(&self.body)
// && place.iter_projections().any(|(place_ref, projection)|
// projection == PlaceElem::Deref && place_ref.ty(self.body.as_ref(), self.tcx).ty.is_mutable_ptr()
// )
}

fn domain_to_petgraph(self, domain: PartialGraph<'tcx>) -> DepGraph<'tcx> {
let mut graph: DiGraph<DepNode<'tcx>, DepEdge> = DiGraph::new();
let mut nodes = FxHashMap::default();
Expand Down
50 changes: 50 additions & 0 deletions crates/flowistry/tests/pdg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,44 @@ fn main() {
})
}

#[test]
fn test_fields_passing_through() {

let input = r#"
use std::num::Wrapping;
fn pass(x2: &Wrapping<u32>) {
println!("{}", x2);
}
fn main() {
let ref mut i = Wrapping(0);
let y = 10;
i.0 += y;
pass(i);
}
"#;
let _ = env_logger::try_init();
flowistry::test_utils::compile(input, move |tcx| {
let def_id = get_main(tcx);
let params = PdgParams::new(tcx, def_id);

let with_edges = flowistry::pdg::compute_pdg(params.with_false_call_edges());

with_edges.generate_graphviz(
"graph.pdf"
).unwrap();


assert!(connects(
tcx,
&with_edges,
"y",
"*x2",
None
));
})
}

#[test]
fn false_call_edges() {
let input = r#"
Expand All @@ -531,6 +569,10 @@ fn main() {
// ));

let with_edges = flowistry::pdg::compute_pdg(params.with_false_call_edges());

with_edges.generate_graphviz(
"graph.pdf"
).unwrap();
assert!(connects(
tcx,
&with_edges,
Expand Down Expand Up @@ -560,6 +602,7 @@ fn get_user_data() -> UserData {
};
}
fn send_user_data(user_data: &UserData) {}
fn send2(user_data2: &UserData) {}
fn modify_vec(v: &mut [i64]) {}
fn main() {
let ref mut p = get_user_data();
Expand Down Expand Up @@ -595,5 +638,12 @@ fn main() {
"user_data",
None,
));
assert!(!connects(
tcx,
with_edges,
"user_data",
"user_data2",
None,
));
});
}

0 comments on commit 0fe3273

Please sign in to comment.