Skip to content

Commit

Permalink
Add is_null flag to PDG graphs
Browse files Browse the repository at this point in the history
Mark each PDG graph with a boolean flag that
represents whether that graph corresponds to the
null pointer or not. The PDG construction algorithm
seems to build one unique graph for all null pointers
in the entire program.
  • Loading branch information
ahomescu committed Jul 23, 2024
1 parent bbe6113 commit cc79e4b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 21 deletions.
14 changes: 13 additions & 1 deletion pdg/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,25 @@ pub fn add_node(
info: None,
};

let ptr_is_null = ptr.map_or(false, |ptr| ptr == 0);
let graph_id = provenance
.as_ref()
.and_then(|p| parent(&node_kind, p))
.map(|pi| pi.gid)
.unwrap_or_else(|| graphs.graphs.push(Graph::new()));
.unwrap_or_else(|| graphs.graphs.push(Graph::new(ptr_is_null)));
let node_id = graphs.graphs[graph_id].nodes.push(node);

// Assert that we're not mixing null and non-null pointers
assert!(
graphs.graphs[graph_id].is_null == ptr_is_null,
"graph[{}].is_null == {:?} != {:x?} for {:?}:{:?}",
graph_id,
graphs.graphs[graph_id].is_null,
ptr,
event,
event_metadata
);

update_provenance(
provenances,
&event.kind,
Expand Down
14 changes: 10 additions & 4 deletions pdg/src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,18 +283,24 @@ impl Display for DisplayNode<'_> {
}

/// A pointer derivation graph, which tracks the handling of one object throughout its lifetime.
#[derive(Debug, Default, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)]
pub struct Graph {
/// The nodes in the graph. Nodes are stored in increasing order by timestamp. The first
/// node, called the "root node", creates the object described by this graph, and all other
/// nodes are derived from it.
#[serde(with = "crate::util::serde::index_vec")]
pub nodes: IndexVec<NodeId, Node>,

/// Whether this graph was built from a null pointer.
pub is_null: bool,
}

impl Graph {
pub fn new() -> Self {
Self::default()
pub fn new(is_null: bool) -> Self {
Self {
nodes: Default::default(),
is_null,
}
}
}

Expand All @@ -313,7 +319,7 @@ impl Display for Graph {
.to_string()
})
.collect::<Vec<_>>();
writeln!(f, "g {{")?;
writeln!(f, "g is_null={} {{", self.is_null)?;
for line in pad_columns(&lines, sep, " ") {
let line = line.trim_end();
writeln!(f, "\t{line}")?;
Expand Down
32 changes: 16 additions & 16 deletions pdg/src/info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ mod test {
/// ```
#[test]
fn unique_interleave() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = 0;
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -345,7 +345,7 @@ mod test {
/// ```
#[test]
fn unique_interleave_onesided() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = 0; // A
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -389,7 +389,7 @@ mod test {
/// ```
#[test]
fn unique_sub_borrow() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = 0;
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -435,7 +435,7 @@ mod test {
/// ```
#[test]
fn unique_sub_borrow_bad() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = 0;
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -481,7 +481,7 @@ mod test {
/// ```
#[test]
fn okay_use_different_fields() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = Point { x: 0, y: 0 };
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -529,7 +529,7 @@ mod test {
/// ```
#[test]
fn same_fields_cousins() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = Point { x: 0, y: 0 };
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -578,7 +578,7 @@ mod test {
/// ```
#[test]
fn field_vs_raw() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = Point { x: 0, y: 0 };
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -624,7 +624,7 @@ mod test {
/// ```
#[test]
fn fields_different_levels() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = Point { x: 0, y: 0 };
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -668,7 +668,7 @@ mod test {
/// ```
#[test]
fn lots_of_siblings() {
let mut g = Graph::default();
let mut g = Graph::new(false);

let (x, y, z) = (0_usize, 1_usize, 2_usize);
let (red, green, _blue) = (0_usize, 1_usize, 2_usize);
Expand Down Expand Up @@ -754,7 +754,7 @@ mod test {
/// ```
#[test]
fn field_no_conflict() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = (1, (2, 3));
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -812,7 +812,7 @@ mod test {
/// ```
#[test]
fn nested_field_no_conflict() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = (1, (2, 3));
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -866,7 +866,7 @@ mod test {
/// ```
#[test]
fn diff_field_conflict() {
let mut g = Graph::default();
let mut g = Graph::new(false);

//let mut a = (1, (2, 3));
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -920,7 +920,7 @@ mod test {
/// ```
#[test]
fn nested_field_conflict() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = (1, (2, 3));
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -982,7 +982,7 @@ mod test {
/// ```
#[test]
fn field_offset_conflict() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = ([1, 2], [3, 4]);
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -1044,7 +1044,7 @@ mod test {
/// ```
#[test]
fn field_offset_no_conflict() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = ([1, 2], [3, 4]);
let a = mk_addr_of_local(&mut g, 0_u32);
Expand Down Expand Up @@ -1114,7 +1114,7 @@ mod test {
/// `rustc` would reject the modified code.
#[test]
fn offset_field_conflict() {
let mut g = Graph::default();
let mut g = Graph::new(false);

// let mut a = ([1, 2], [3, 4]);
// let p = &mut a;
Expand Down

0 comments on commit cc79e4b

Please sign in to comment.