From d517c480971e4235e6233ee66b4dc6c2712dc4bb Mon Sep 17 00:00:00 2001 From: Andrei Homescu Date: Fri, 19 Jul 2024 22:12:05 -0700 Subject: [PATCH 1/4] Handle nested fields and other projections Record field and index projections for pointers by recording a Project event with a base and target pointer pair. --- analysis/runtime/src/events.rs | 8 +- analysis/runtime/src/handlers.rs | 4 +- dynamic_instrumentation/src/instrument.rs | 253 ++++++++++++------ dynamic_instrumentation/src/into_operand.rs | 14 +- .../src/mir_utils/deref.rs | 24 -- pdg/src/builder.rs | 8 +- pdg/src/graph.rs | 8 +- pdg/src/info.rs | 89 +++--- 8 files changed, 238 insertions(+), 170 deletions(-) diff --git a/analysis/runtime/src/events.rs b/analysis/runtime/src/events.rs index 9338119b39..1dea82d532 100644 --- a/analysis/runtime/src/events.rs +++ b/analysis/runtime/src/events.rs @@ -30,10 +30,8 @@ pub enum EventKind { CopyRef, - /// Field projection. Used for operations like `_2 = &(*_1).0`. Nested field - /// accesses like `_4 = &(*_1).x.y.z` are broken into multiple `Node`s, each - /// covering one level. - Field(Pointer, u32), + /// Projection. Used for operations like `_2 = &(*_1).0`. + Project(Pointer, Pointer), Alloc { size: usize, @@ -90,7 +88,7 @@ impl Debug for EventKind { use EventKind::*; match *self { CopyPtr(ptr) => write!(f, "copy(0x{:x})", ptr), - Field(ptr, id) => write!(f, "field(0x{:x}, {})", ptr, id), + Project(ptr, new_ptr) => write!(f, "project(0x{:x}, 0x{:x})", ptr, new_ptr), Alloc { size, ptr } => { write!(f, "malloc({}) -> 0x{:x}", size, ptr) } diff --git a/analysis/runtime/src/handlers.rs b/analysis/runtime/src/handlers.rs index 03b2075f66..1b121656d2 100644 --- a/analysis/runtime/src/handlers.rs +++ b/analysis/runtime/src/handlers.rs @@ -110,10 +110,10 @@ pub const HOOK_FUNCTIONS: &[&str] = &[ hook_fn!(offset), ]; -pub fn ptr_field(mir_loc: MirLocId, ptr: usize, field_id: u32) { +pub fn ptr_project(mir_loc: MirLocId, ptr: usize, new_ptr: usize) { RUNTIME.send_event(Event { mir_loc, - kind: EventKind::Field(ptr, field_id), + kind: EventKind::Project(ptr, new_ptr), }); } diff --git a/dynamic_instrumentation/src/instrument.rs b/dynamic_instrumentation/src/instrument.rs index ec31abd0ca..7bcde0f143 100644 --- a/dynamic_instrumentation/src/instrument.rs +++ b/dynamic_instrumentation/src/instrument.rs @@ -8,7 +8,9 @@ use indexmap::IndexSet; use log::{debug, trace}; use rustc_ast::Mutability; use rustc_index::vec::Idx; -use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{ + MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor, +}; use rustc_middle::mir::{ BasicBlock, BasicBlockData, Body, BorrowKind, ClearCrossCrate, HasLocalDecls, Local, LocalDecl, Location, Operand, Place, PlaceElem, ProjectionElem, Rvalue, Safety, SourceInfo, SourceScope, @@ -24,7 +26,8 @@ use std::sync::Mutex; use crate::arg::{ArgKind, InstrumentationArg}; use crate::hooks::Hooks; -use crate::mir_utils::{has_outer_deref, remove_outer_deref, strip_all_deref}; +use crate::into_operand::IntoOperand; +use crate::mir_utils::remove_outer_deref; use crate::point::InstrumentationApplier; use crate::point::{cast_ptr_to_usize, InstrumentationPriority}; use crate::point::{ @@ -343,31 +346,175 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { self.super_place(place, context, location); - let field_fn = self.hooks().find("ptr_field"); + if !place.is_indirect() { + return; + } + if !context.is_use() { + return; + } + + let copy_fn = self.hooks().find("ptr_copy"); + let project_fn = self.hooks().find("ptr_project"); + let load_fn = self.hooks().find("ptr_load"); + let load_value_fn = self.hooks().find("load_value"); + let store_fn = self.hooks().find("ptr_store"); + + let tcx = self.tcx(); + + // Instrument nested projections and derefs + let mut proj_iter = place.iter_projections().peekable(); - let base_ty = self.local_decls()[place.local].ty; + // Skip over the initial projections of the local since we do + // not want to take its address; we only care about the ones + // past the first dereference since at that point we have an + // actual pointer. + while let Some((_, elem)) = proj_iter.peek() { + if matches!(elem, PlaceElem::Deref) { + break; + } + let _ = proj_iter.next(); + } + + while let Some((inner_deref_base, PlaceElem::Deref)) = proj_iter.next() { + // Find the next Deref or end of projections + let (outer_deref_base, have_outer_deref) = loop { + match proj_iter.peek() { + Some((base, PlaceElem::Deref)) => break (base.clone(), true), + // Reached the end, we can use the full place + None => break (place.as_ref(), false), + _ => { + let _ = proj_iter.next(); + } + } + }; - // Instrument field projections on raw-ptr places - if is_region_or_unsafe_ptr(base_ty) && context.is_use() { - for (base, elem) in place.iter_projections() { - if let PlaceElem::Field(field, _) = elem { - let proj_dest = || { + // We need to convert the inner base into an operand that + // we can pass to `.source()` below since we don't have + // an implementation of `Source for PlaceRef`. + let inner_deref_op: Operand = inner_deref_base.op(tcx); + + // We have some other elements between the two projections + let have_other_projections = + outer_deref_base.projection.len() - inner_deref_base.projection.len() > 1; + if have_other_projections { + let dest = || { + if have_outer_deref { // Only the last field projection gets a destination - self.assignment() - .as_ref() - .map(|(dest, _)| dest) - .copied() - .filter(|_| base.projection.len() == place.projection.len() - 1) - }; - self.loc(location, location, field_fn) - .arg_var(place.local) - .arg_index_of(field) - .source(place) - .dest_from(proj_dest) - .add_to(self); + return None; + } + if !context.is_borrow() + && !matches!( + context, + NonMutatingUse(NonMutatingUseContext::AddressOf) + | MutatingUse(MutatingUseContext::AddressOf) + ) + { + // The only cases we care about here are the same as + // `copy_fn`: taking the address of a projection, + // e.g., `_1 = &((*_2).x)`. + return None; + } + self.assignment().as_ref().map(|(dest, _)| dest).copied() + }; + + // There are non-deref projection elements between the two derefs. + // Add a Project event between the start pointer of those field/index + // projections and their final address. + // + // E.g. for `p.*` and `p.*.x.y.*` the inner base is `p` and + // the outer base is `p.*.x.y`. The inner one is already a pointer + // so we pass it by value, but the outer base is a field of + // a structure (pointed to by the inner base), + // which means we need to take the address of the field. + // The event we emit is `Project(p, &(p.*.x.y))`. + self.loc(location, location, project_fn) + .arg_var(inner_deref_base) + .arg_addr_of(outer_deref_base.clone()) + .source(&inner_deref_op) + .dest_from(dest) + .add_to(self); + } + + use PlaceContext::*; + if let Some(ptr_fn) = match context { + // We are just loading the value of the inner dereference + // so we can offset from it to get the pointer of the outer one + _ if have_outer_deref => Some(load_fn), + + NonMutatingUse(NonMutatingUseContext::Copy) + | NonMutatingUse(NonMutatingUseContext::Move) => Some(load_fn), + + // We get here with !have_outer_deref, so this is the + // full access to the final place. Use the actual operation + // that depends on the context the place is used in. + MutatingUse(MutatingUseContext::Store) + | MutatingUse(MutatingUseContext::Call) + | MutatingUse(MutatingUseContext::AsmOutput) => Some(store_fn), + + NonMutatingUse(NonMutatingUseContext::ShallowBorrow) + | NonMutatingUse(NonMutatingUseContext::SharedBorrow) + | NonMutatingUse(NonMutatingUseContext::UniqueBorrow) + | NonMutatingUse(NonMutatingUseContext::AddressOf) + | MutatingUse(MutatingUseContext::Borrow) + | MutatingUse(MutatingUseContext::AddressOf) => Some(copy_fn), + + NonMutatingUse(NonMutatingUseContext::Inspect) + | NonMutatingUse(NonMutatingUseContext::Projection) + | MutatingUse(MutatingUseContext::SetDiscriminant) + | MutatingUse(MutatingUseContext::Deinit) + | MutatingUse(MutatingUseContext::Yield) + | MutatingUse(MutatingUseContext::Drop) + | MutatingUse(MutatingUseContext::Projection) + | MutatingUse(MutatingUseContext::Retag) + | NonUse(_) => None, + } { + let dest = || { + // The only pattern we can handle here is + // taking an address of a Deref, e.g., + // `_1 = &(*_2)`. + if ptr_fn != copy_fn { + return None; + } + if have_other_projections { + // Projections are handled separately above. + return None; + } + self.assignment().as_ref().map(|(dest, _)| dest).copied() + }; + + // We take the address of the outer dereference here. + // E.g. `LoadAddr(&(p.*.x.y))` + let ib = self + .loc(location, location, ptr_fn) + .arg_addr_of(outer_deref_base) + .source(&inner_deref_op) + .dest_from(dest); + + // If we are copying a pointer with projections, e.g. + // `_1 = &(*_2).x`, we emit that as a Project event instead. + if ptr_fn != copy_fn || !have_other_projections { + ib.add_to(self); } } + + if have_outer_deref { + // Add an event for loading the base of the next projection. + // Note that if the deref is followed by other projections, + // we need to include all of them, e.g., if there is a field + // then we're loading from it and not the base structure. + // This happens to be the same as the base of the outer deref, + // so we just use that as the value. + // + // E.g. for `p.*.x.y.*` the outer base is `p.*.x.y` + // and we emit `LoadValue(p.*.x.y)`. + self.loc(location, location, load_value_fn) + .arg_var(outer_deref_base.clone()) + .add_to(self); + } } + // If this algorithm is correct, + // we should have consumed the entire iterator + assert!(proj_iter.peek().is_none()); } fn visit_assign(&mut self, dest: &Place<'tcx>, value: &Rvalue<'tcx>, location: Location) { @@ -377,9 +524,7 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { let ptr_to_int_fn = self.hooks().find("ptr_to_int"); let load_value_fn = self.hooks().find("load_value"); let store_value_fn = self.hooks().find("store_value"); - let store_fn = self.hooks().find("ptr_store"); let store_addr_taken_fn = self.hooks().find("ptr_store_addr_taken"); - let load_fn = self.hooks().find("ptr_load"); let dest = *dest; self.with_assignment((dest, value.clone()), |this| { @@ -391,7 +536,6 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { let op_ty = |op: &Operand<'tcx>| op.ty(&locals, ctx); let place_ty = |p: &Place<'tcx>| p.ty(&locals, ctx).ty; - let local_ty = |p: &Place| place_ty(&p.local.into()); let value_ty = value.ty(self, self.tcx()); self.visit_place( @@ -427,33 +571,8 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { _ => (), } - let mut add_load_instr = |p: &Place<'tcx>| { - self.loc(location, location, load_fn) - .arg_var(p.local) - .source(&remove_outer_deref(*p, ctx)) - .add_to(self); - }; - - // add instrumentation for load-from-address operations - match value { - Rvalue::Use(Operand::Copy(p) | Operand::Move(p)) - if p.is_indirect() && is_region_or_unsafe_ptr(local_ty(p)) => - { - add_load_instr(p) - } - _ => (), - } - match value { _ if dest.is_indirect() => { - // Strip all derefs to set base_dest to the pointer that is deref'd - let base_dest = strip_all_deref(&dest, self.tcx()); - - self.loc(location, location, store_fn) - .arg_var(base_dest) - .source(&remove_outer_deref(dest, self.tcx())) - .add_to(self); - if is_region_or_unsafe_ptr(value_ty) { self.loc(location, location.successor_within_block(), store_value_fn) .arg_var(dest) @@ -473,19 +592,7 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { } } _ if !is_region_or_unsafe_ptr(value_ty) => {} - Rvalue::AddressOf(_, p) - if has_outer_deref(p) - && is_region_or_unsafe_ptr(place_ty(&remove_outer_deref(*p, self.tcx()))) => - { - let source = remove_outer_deref(*p, self.tcx()); - // Instrument which local's address is taken - self.loc(location, location.successor_within_block(), copy_fn) - .arg_var(dest) - .source(&source) - .dest(&dest) - .add_to(self); - } - Rvalue::AddressOf(_, p) => { + Rvalue::AddressOf(_, p) if !p.is_indirect() => { // Instrument which local's address is taken self.loc(location, location.successor_within_block(), addr_local_fn) .arg_var(dest) @@ -531,28 +638,6 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { .dest(&dest) .add_to(self); } - Rvalue::Ref(_, bkind, p) - if has_outer_deref(p) - && is_region_or_unsafe_ptr(place_ty(&remove_outer_deref(*p, self.tcx()))) => - { - // this is a reborrow or field reference, i.e. _2 = &(*_1) - let source = remove_outer_deref(*p, self.tcx()); - if let BorrowKind::Mut { .. } = bkind { - // Instrument which local's address is taken - self.loc(location, location, copy_fn) - .arg_addr_of(*p) - .source(&source) - .dest(&dest) - .add_to(self); - } else { - // Instrument immutable borrows by tracing the reference itself - self.loc(location, location.successor_within_block(), copy_fn) - .arg_var(dest) - .source(&source) - .dest(&dest) - .add_to(self); - }; - } Rvalue::Ref(_, bkind, p) if !p.is_indirect() => { let source = remove_outer_deref(*p, self.tcx()); if let BorrowKind::Mut { .. } = bkind { diff --git a/dynamic_instrumentation/src/into_operand.rs b/dynamic_instrumentation/src/into_operand.rs index fcf0c4ed58..49c9527f5e 100644 --- a/dynamic_instrumentation/src/into_operand.rs +++ b/dynamic_instrumentation/src/into_operand.rs @@ -1,5 +1,5 @@ use rustc_middle::{ - mir::{Constant, ConstantKind, Local, Operand, Place}, + mir::{Constant, ConstantKind, Local, Operand, Place, PlaceRef}, ty::{self, ParamEnv, TyCtxt}, }; use rustc_span::DUMMY_SP; @@ -10,11 +10,21 @@ pub trait IntoOperand<'tcx> { } impl<'tcx> IntoOperand<'tcx> for Place<'tcx> { - fn op(self, _tcx: TyCtxt) -> Operand<'tcx> { + fn op(self, _tcx: TyCtxt<'tcx>) -> Operand<'tcx> { Operand::Copy(self) } } +impl<'tcx> IntoOperand<'tcx> for PlaceRef<'tcx> { + fn op(self, tcx: TyCtxt<'tcx>) -> Operand<'tcx> { + let place = Place { + local: self.local, + projection: tcx.mk_place_elems(self.projection.iter()), + }; + place.op(tcx) + } +} + impl<'tcx> IntoOperand<'tcx> for u32 { fn op(self, tcx: TyCtxt<'tcx>) -> Operand<'tcx> { make_const(tcx, self) diff --git a/dynamic_instrumentation/src/mir_utils/deref.rs b/dynamic_instrumentation/src/mir_utils/deref.rs index 75418e7076..a9b136a273 100644 --- a/dynamic_instrumentation/src/mir_utils/deref.rs +++ b/dynamic_instrumentation/src/mir_utils/deref.rs @@ -3,30 +3,6 @@ use rustc_middle::{ ty::TyCtxt, }; -pub fn has_outer_deref(p: &Place) -> bool { - matches!( - p.iter_projections().last(), - Some((_, ProjectionElem::Deref)) - ) -} - -/// Get the inner-most dereferenced [`Place`]. -pub fn strip_all_deref<'tcx>(p: &Place<'tcx>, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - let mut base_dest = p.as_ref(); - let mut place_ref = p.clone().as_ref(); - while let Some((cur_ref, proj)) = place_ref.last_projection() { - if let ProjectionElem::Deref = proj { - base_dest = cur_ref; - } - place_ref = cur_ref; - } - - Place { - local: base_dest.local, - projection: tcx.intern_place_elems(base_dest.projection), - } -} - /// Strip the initital [`Deref`](ProjectionElem::Deref) /// from a [`projection`](PlaceRef::projection) sequence. pub fn remove_outer_deref<'tcx>(p: Place<'tcx>, tcx: TyCtxt<'tcx>) -> Place<'tcx> { diff --git a/pdg/src/builder.rs b/pdg/src/builder.rs index e8b30ef3e4..d14ca1334e 100644 --- a/pdg/src/builder.rs +++ b/pdg/src/builder.rs @@ -44,7 +44,7 @@ impl EventKindExt for EventKind { use EventKind::*; Some(match *self { CopyPtr(lhs) => lhs, - Field(ptr, ..) => ptr, + Project(ptr, ..) => ptr, Free { ptr } => ptr, Ret(ptr) => ptr, LoadAddr(ptr) => ptr, @@ -70,7 +70,7 @@ impl EventKindExt for EventKind { Realloc { .. } => NodeKind::Alloc(1), Free { .. } => NodeKind::Free, CopyPtr(..) | CopyRef => NodeKind::Copy, - Field(_, field) => NodeKind::Field(field.into()), + Project(base_ptr, new_ptr) => NodeKind::Project(new_ptr - base_ptr), LoadAddr(..) => NodeKind::LoadAddr, StoreAddr(..) => NodeKind::StoreAddr, StoreAddrTaken(..) => NodeKind::StoreAddr, @@ -188,7 +188,7 @@ pub fn add_node( if let Some((gid, _)) = latest_assignment { if let Some((nid, n)) = graphs.graphs[gid].nodes.iter_enumerated().rev().next() { - if let NodeKind::Field(..) = n.kind { + if let NodeKind::Project(..) = n.kind { return Some((gid, nid)); } } @@ -197,7 +197,7 @@ pub fn add_node( if !matches!(event.kind, EventKind::AddrOfLocal(..)) && src.projection.is_empty() { latest_assignment - } else if let EventKind::Field(..) = event.kind { + } else if let EventKind::Project(..) = event.kind { latest_assignment } else { provenance diff --git a/pdg/src/graph.rs b/pdg/src/graph.rs index e921018e9a..01b9fa3ff6 100644 --- a/pdg/src/graph.rs +++ b/pdg/src/graph.rs @@ -2,7 +2,7 @@ use c2rust_analysis_rt::mir_loc::{self, DefPathHash, Func}; use c2rust_analysis_rt::mir_loc::{FuncId, MirPlace}; use rustc_index::newtype_index; use rustc_index::vec::IndexVec; -use rustc_middle::mir::{BasicBlock, Field, Local}; +use rustc_middle::mir::{BasicBlock, Local}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::fmt::Display; use std::{ @@ -25,9 +25,7 @@ pub enum NodeKind { /// [`Field`] projection. /// /// Used for operations like `_2 = &(*_1).0`. - /// Nested field accesses like `_4 = &(*_1).x.y.z` - /// are broken into multiple [`Node`]s, each covering one level. - Field(#[serde(with = "crate::util::serde::FieldDef")] Field), + Project(usize), /// Pointer arithmetic. /// @@ -121,7 +119,7 @@ impl Display for NodeKind { use NodeKind::*; match self { Copy => write!(f, "copy"), - Field(field) => write!(f, "field.{}", field.as_usize()), + Project(offset) => write!(f, "project.{offset}"), Offset(offset) => write!(f, "offset[{offset}]"), AddrOfLocal(local) => write!(f, "&{local:?}"), _AddrOfStatic(static_) => write!(f, "&'static {static_:?}"), diff --git a/pdg/src/info.rs b/pdg/src/info.rs index ad26b23e5f..1a247acfba 100644 --- a/pdg/src/info.rs +++ b/pdg/src/info.rs @@ -1,5 +1,4 @@ use crate::graph::{Graph, Graphs, Node, NodeId, NodeKind}; -use rustc_middle::mir::Field; use serde::{Deserialize, Serialize}; use std::cmp::{max, min}; use std::collections::{HashMap, HashSet}; @@ -8,6 +7,9 @@ use std::fmt::{self, Debug, Display, Formatter}; /// Force an import of [`Node`] just for docs. const _: Option = None; +/// The identity of a field of a structure is its offset. +type Field = usize; + /// Information generated from the PDG proper that is queried by static analysis. /// /// Includes information about what kinds of [`Node`]s the [`Node`] flows to, @@ -111,7 +113,7 @@ fn collect_children(g: &Graph) -> HashMap)>> { .rev() .filter_map(|(child, child_node)| Some((child_node.source?, child, child_node))) { - if let NodeKind::Field(f) = child_node.kind { + if let NodeKind::Project(f) = child_node.kind { let my_children = children .remove(&child) @@ -224,7 +226,6 @@ mod test { use super::*; use c2rust_analysis_rt::mir_loc::Func; use c2rust_analysis_rt::mir_loc::FuncId; - use rustc_middle::mir::Field; use rustc_middle::mir::Local; fn mk_node(g: &mut Graph, kind: NodeKind, source: Option) -> NodeId { @@ -255,8 +256,8 @@ mod test { mk_node(g, NodeKind::StoreAddr, Some(source)) } - fn mk_field(g: &mut Graph, source: NodeId, field: impl Into) -> NodeId { - mk_node(g, NodeKind::Field(field.into()), Some(source)) + fn mk_project(g: &mut Graph, source: NodeId, field: impl Into) -> NodeId { + mk_node(g, NodeKind::Project(field.into()), Some(source)) } fn mk_offset(g: &mut Graph, source: NodeId, i: isize) -> NodeId { @@ -485,10 +486,10 @@ mod test { // let mut a = Point { x: 0, y: 0 }; let a = mk_addr_of_local(&mut g, 0_u32); // let b = &mut a.x; - let b11 = mk_field(&mut g, a, 0_u32); + let b11 = mk_project(&mut g, a, 0_usize); let b1 = mk_copy(&mut g, b11); // let c = &mut a.y; - let c11 = mk_field(&mut g, a, 1_u32); + let c11 = mk_project(&mut g, a, 1_usize); let c1 = mk_copy(&mut g, c11); // *b = 1; let b2 = mk_store_addr(&mut g, b1); @@ -535,17 +536,17 @@ mod test { // let j = &mut a; let j = mk_copy(&mut g, a); // let b = &mut j.x; - let b11 = mk_field(&mut g, j, 0_u32); + let b11 = mk_project(&mut g, j, 0_usize); let b1 = mk_copy(&mut g, b11); // let c = &mut j.x; - let c11 = mk_field(&mut g, j, 0_u32); + let c11 = mk_project(&mut g, j, 0_usize); let c1 = mk_copy(&mut g, c11); // *b = 1; let b2 = mk_store_addr(&mut g, b1); // *c = 2; let c2 = mk_store_addr(&mut g, c1); // *(a.y) = 3; - let d1 = mk_field(&mut g, a, 1_u32); + let d1 = mk_project(&mut g, a, 1_usize); let d2 = mk_store_addr(&mut g, d1); let pdg = build_pdg(g); @@ -584,7 +585,7 @@ mod test { // let b = &mut a; let b1 = mk_copy(&mut g, a); // let c = &mut a.y; - let c11 = mk_field(&mut g, a, 1_u32); + let c11 = mk_project(&mut g, a, 1_usize); let c1 = mk_copy(&mut g, c11); // *c = 2; let c2 = mk_store_addr(&mut g, c1); @@ -630,10 +631,10 @@ mod test { // let b = &mut a; let b1 = mk_copy(&mut g, a); // let c = &mut b.y; - let c1 = mk_field(&mut g, a, 1_u32); + let c1 = mk_project(&mut g, a, 1_usize); let c2 = mk_copy(&mut g, c1); // let bb = &mut b.y; - let bb = mk_field(&mut g, b1, 1_u32); + let bb = mk_project(&mut g, b1, 1_usize); let bb1 = mk_copy(&mut g, bb); // *c = 2; let c3 = mk_store_addr(&mut g, c2); @@ -669,20 +670,20 @@ mod test { fn lots_of_siblings() { let mut g = Graph::default(); - let (x, y, z) = (0_u32, 1_u32, 2_u32); - let (red, green, _blue) = (0_u32, 1_u32, 2_u32); + let (x, y, z) = (0_usize, 1_usize, 2_usize); + let (red, green, _blue) = (0_usize, 1_usize, 2_usize); // let mut a = ColorPoint { x: 0, y: 0, z: Color { r: 100, g: 100, b: 100 } }; let a = mk_addr_of_local(&mut g, 0_u32); // let b = &mut a.x; - let bb1 = mk_field(&mut g, a, x); + let bb1 = mk_project(&mut g, a, x); let b1 = mk_copy(&mut g, bb1); // let c = &mut a.y; - let cc1 = mk_field(&mut g, a, y); + let cc1 = mk_project(&mut g, a, y); let c1 = mk_copy(&mut g, cc1); // a.z.r = 200; - let x1 = mk_field(&mut g, a, z); - let x2 = mk_field(&mut g, x1, red); + let x1 = mk_project(&mut g, a, z); + let x2 = mk_project(&mut g, x1, red); let x3 = mk_store_addr(&mut g, x2); // *b = 4; let b2 = mk_store_addr(&mut g, b1); @@ -693,19 +694,19 @@ mod test { // *d = ColorPoint { x: 0, y: 0, z: Color { r: 20, g: 200, b: 20 } }; let d2 = mk_store_addr(&mut g, d1); // let e = &mut a.z; - let ee = mk_field(&mut g, a, z); + let ee = mk_project(&mut g, a, z); let e = mk_copy(&mut g, ee); // let f = &mut e.g; - let ff1 = mk_field(&mut g, e, green); + let ff1 = mk_project(&mut g, e, green); let f1 = mk_copy(&mut g, ff1); // let g = &mut e.g; - let ggg = mk_field(&mut g, e, green); + let ggg = mk_project(&mut g, e, green); let gg = mk_copy(&mut g, ggg); // *f = 3; let f2 = mk_store_addr(&mut g, f1); // a.z.r = 100; - let x4 = mk_field(&mut g, a, z); - let x5 = mk_field(&mut g, x4, green); + let x4 = mk_project(&mut g, a, z); + let x5 = mk_project(&mut g, x4, green); let x6 = mk_store_addr(&mut g, x5); let pdg = build_pdg(g); @@ -758,10 +759,10 @@ mod test { // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0; - let x1 = mk_field(&mut g, a, 0_u32); + let x1 = mk_project(&mut g, a, 0_usize); let x2 = mk_copy(&mut g, x1); // let y = &mut a.1; - let y1 = mk_field(&mut g, a, 1_u32); + let y1 = mk_project(&mut g, a, 1_usize); let y2 = mk_copy(&mut g, y1); // *x = 1; let x3 = mk_store_addr(&mut g, x2); @@ -816,12 +817,12 @@ mod test { // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.1.0; - let x1 = mk_field(&mut g, a, 1_u32); - let x2 = mk_field(&mut g, x1, 0_u32); + let x1 = mk_project(&mut g, a, 1_usize); + let x2 = mk_project(&mut g, x1, 0_usize); let x3 = mk_copy(&mut g, x2); // let y = &mut a.1.1; - let y1 = mk_field(&mut g, a, 1_u32); - let y2 = mk_field(&mut g, y1, 1_u32); + let y1 = mk_project(&mut g, a, 1_usize); + let y2 = mk_project(&mut g, y1, 1_usize); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); @@ -870,16 +871,16 @@ mod test { //let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); //let mut x = &mut a.1; - let x1 = mk_field(&mut g, a, 1_u32); + let x1 = mk_project(&mut g, a, 1_usize); let x2 = mk_copy(&mut g, x1); //let mut y = &mut a.1; - let y1 = mk_field(&mut g, a, 1_u32); + let y1 = mk_project(&mut g, a, 1_usize); let y2 = mk_copy(&mut g, y1); // *(x.0) = 4; - let x3 = mk_field(&mut g, x2, 0_u32); + let x3 = mk_project(&mut g, x2, 0_usize); let x4 = mk_store_addr(&mut g, x3); // *(y.1) = 2; - let y3 = mk_field(&mut g, y2, 1_u32); + let y3 = mk_project(&mut g, y2, 1_usize); let y4 = mk_store_addr(&mut g, y3); let pdg = build_pdg(g); @@ -924,12 +925,12 @@ mod test { // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.1.0; - let x1 = mk_field(&mut g, a, 1_u32); - let x2 = mk_field(&mut g, x1, 0_u32); + let x1 = mk_project(&mut g, a, 1_usize); + let x2 = mk_project(&mut g, x1, 0_usize); let x3 = mk_copy(&mut g, x2); // let y = &mut a.1.0; - let y1 = mk_field(&mut g, a, 1_u32); - let y2 = mk_field(&mut g, y1, 0_u32); + let y1 = mk_project(&mut g, a, 1_usize); + let y2 = mk_project(&mut g, y1, 0_usize); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); @@ -986,11 +987,11 @@ mod test { // let mut a = ([1, 2], [3, 4]); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0[0]; - let x1 = mk_field(&mut g, a, 1_u32); + let x1 = mk_project(&mut g, a, 1_usize); let x2 = mk_offset(&mut g, x1, 0); let x3 = mk_copy(&mut g, x2); // let y = &mut a.0[1]; - let y1 = mk_field(&mut g, a, 1_u32); + let y1 = mk_project(&mut g, a, 1_usize); let y2 = mk_offset(&mut g, y1, 1); let y3 = mk_copy(&mut g, y2); // *x = 1; @@ -1048,11 +1049,11 @@ mod test { // let mut a = ([1, 2], [3, 4]); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0[0]; - let x1 = mk_field(&mut g, a, 0_u32); + let x1 = mk_project(&mut g, a, 0_usize); let x2 = mk_offset(&mut g, x1, 0); let x3 = mk_copy(&mut g, x2); // let y = &mut a.1[0]; - let y1 = mk_field(&mut g, a, 1_u32); + let y1 = mk_project(&mut g, a, 1_usize); let y2 = mk_offset(&mut g, y1, 0); let y3 = mk_copy(&mut g, y2); // *x = 1; @@ -1120,11 +1121,11 @@ mod test { let p = mk_addr_of_local(&mut g, 0_u32); // let x = &mut (*p)[0].0; let x1 = mk_offset(&mut g, p, 0); - let x2 = mk_field(&mut g, x1, 0_u32); + let x2 = mk_project(&mut g, x1, 0_usize); let x3 = mk_copy(&mut g, x2); // let y = &mut (*p)[0].1; let y1 = mk_offset(&mut g, p, 0); - let y2 = mk_field(&mut g, y1, 1_u32); + let y2 = mk_project(&mut g, y1, 1_usize); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); From 8af09d10bd000947f3c005fce40e6d27cc7308f8 Mon Sep 17 00:00:00 2001 From: Andrei Homescu Date: Tue, 23 Jul 2024 23:24:09 -0700 Subject: [PATCH 2/4] Keep track of unique projection combinations in Project Add an index value to Project events to differentiate between different projections with the same pointer offset, e.g., (*p).x and (*p).x.a if a is the first field of the structure. This is implemented as an IndexSet> where each element is a unique combination of field projections. The Project index points to an element in this set. --- Cargo.lock | 1 + analysis/runtime/Cargo.toml | 1 + analysis/runtime/src/events.rs | 10 ++- analysis/runtime/src/handlers.rs | 4 +- analysis/runtime/src/metadata.rs | 10 ++- dynamic_instrumentation/src/instrument.rs | 28 +++++++- dynamic_instrumentation/src/into_operand.rs | 14 ++++ dynamic_instrumentation/src/point/mod.rs | 7 ++ pdg/src/builder.rs | 2 +- pdg/src/graph.rs | 4 +- pdg/src/info.rs | 80 ++++++++++----------- 11 files changed, 111 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2a8d9e267f..4f5a93ec53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,6 +198,7 @@ dependencies = [ "crossbeam-utils", "enum_dispatch", "fs-err", + "indexmap", "once_cell", "serde", ] diff --git a/analysis/runtime/Cargo.toml b/analysis/runtime/Cargo.toml index 7f2b2bc538..14436d99c4 100644 --- a/analysis/runtime/Cargo.toml +++ b/analysis/runtime/Cargo.toml @@ -19,3 +19,4 @@ enum_dispatch = "0.3" fs-err = "2" crossbeam-queue = "0.3" crossbeam-utils = "0.8" +indexmap = { version = "1.9", features = ["serde"] } diff --git a/analysis/runtime/src/events.rs b/analysis/runtime/src/events.rs index 1dea82d532..1d536bd43c 100644 --- a/analysis/runtime/src/events.rs +++ b/analysis/runtime/src/events.rs @@ -31,7 +31,11 @@ pub enum EventKind { CopyRef, /// Projection. Used for operations like `_2 = &(*_1).0`. - Project(Pointer, Pointer), + /// The third value is a "projection index" that points to an element + /// of the projections data structure in the metadata. It is used to + /// disambiguate between different projections with the same pointer, + /// e.g., `(*p).x` and `(*p).x.a` where `a` is at offset 0. + Project(Pointer, Pointer, usize), Alloc { size: usize, @@ -88,7 +92,9 @@ impl Debug for EventKind { use EventKind::*; match *self { CopyPtr(ptr) => write!(f, "copy(0x{:x})", ptr), - Project(ptr, new_ptr) => write!(f, "project(0x{:x}, 0x{:x})", ptr, new_ptr), + Project(ptr, new_ptr, idx) => { + write!(f, "project(0x{:x}, 0x{:x}, [{}])", ptr, new_ptr, idx) + } Alloc { size, ptr } => { write!(f, "malloc({}) -> 0x{:x}", size, ptr) } diff --git a/analysis/runtime/src/handlers.rs b/analysis/runtime/src/handlers.rs index 1b121656d2..8876db38b1 100644 --- a/analysis/runtime/src/handlers.rs +++ b/analysis/runtime/src/handlers.rs @@ -110,10 +110,10 @@ pub const HOOK_FUNCTIONS: &[&str] = &[ hook_fn!(offset), ]; -pub fn ptr_project(mir_loc: MirLocId, ptr: usize, new_ptr: usize) { +pub fn ptr_project(mir_loc: MirLocId, ptr: usize, new_ptr: usize, proj_idx: usize) { RUNTIME.send_event(Event { mir_loc, - kind: EventKind::Project(ptr, new_ptr), + kind: EventKind::Project(ptr, new_ptr, proj_idx), }); } diff --git a/analysis/runtime/src/metadata.rs b/analysis/runtime/src/metadata.rs index 0856bf8d6e..8f5b51a5a9 100644 --- a/analysis/runtime/src/metadata.rs +++ b/analysis/runtime/src/metadata.rs @@ -1,3 +1,4 @@ +use indexmap::IndexSet; use std::{ collections::HashMap, fmt::{self, Debug, Formatter}, @@ -13,6 +14,7 @@ use crate::mir_loc::{Func, FuncId, MirLoc, MirLocId}; pub struct Metadata { pub locs: Vec, pub functions: HashMap, + pub projections: IndexSet>, } impl Metadata { @@ -46,11 +48,17 @@ impl FromIterator for Metadata { fn from_iter>(iter: I) -> Self { let mut locs = Vec::new(); let mut functions = HashMap::new(); + let mut projections = IndexSet::new(); for metadata in iter { locs.extend(metadata.locs); functions.extend(metadata.functions); + projections.extend(metadata.projections); + } + Self { + locs, + functions, + projections, } - Self { locs, functions } } } diff --git a/dynamic_instrumentation/src/instrument.rs b/dynamic_instrumentation/src/instrument.rs index 7bcde0f143..24409d4a0d 100644 --- a/dynamic_instrumentation/src/instrument.rs +++ b/dynamic_instrumentation/src/instrument.rs @@ -29,6 +29,7 @@ use crate::hooks::Hooks; use crate::into_operand::IntoOperand; use crate::mir_utils::remove_outer_deref; use crate::point::InstrumentationApplier; +use crate::point::ProjectionSet; use crate::point::{cast_ptr_to_usize, InstrumentationPriority}; use crate::point::{ CollectAddressTakenLocals, CollectInstrumentationPoints, RewriteAddressTakenLocals, @@ -39,6 +40,7 @@ use crate::util::Convert; pub struct Instrumenter { mir_locs: Mutex>, functions: Mutex>, + projections: Mutex>>, } impl Instrumenter { @@ -73,9 +75,14 @@ impl Instrumenter { pub fn finalize(&self, metadata_path: &Path) -> anyhow::Result<()> { let mut locs = self.mir_locs.lock().unwrap(); let mut functions = self.functions.lock().unwrap(); + let projections = std::mem::take(&mut *self.projections.lock().unwrap()); let locs = locs.drain(..).collect::>(); let functions = functions.drain().collect::>(); - let metadata = Metadata { locs, functions }; + let metadata = Metadata { + locs, + functions, + projections, + }; let bytes = bincode::serialize(&metadata).context("Location serialization failed")?; let mut file = OpenOptions::new() .append(true) @@ -116,6 +123,12 @@ impl Instrumenter { } } +impl ProjectionSet for Instrumenter { + fn add_proj(&self, proj: Vec) -> usize { + self.projections.lock().unwrap().insert_full(proj).0 + } +} + fn is_shared_or_unsafe_ptr(ty: Ty) -> bool { ty.is_unsafe_ptr() || (ty.is_region_ptr() && !ty.is_mutable_ptr()) } @@ -377,7 +390,14 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { while let Some((inner_deref_base, PlaceElem::Deref)) = proj_iter.next() { // Find the next Deref or end of projections + // Meanwhile, collect all `Field`s into a vector that we + // can add to the `projections` IndexSet + let mut fields = vec![]; let (outer_deref_base, have_outer_deref) = loop { + if let Some((_, PlaceElem::Field(idx, _))) = proj_iter.peek() { + fields.push(idx.index()); + } + match proj_iter.peek() { Some((base, PlaceElem::Deref)) => break (base.clone(), true), // Reached the end, we can use the full place @@ -397,6 +417,8 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { let have_other_projections = outer_deref_base.projection.len() - inner_deref_base.projection.len() > 1; if have_other_projections { + let proj_idx = self.projections.add_proj(fields); + let dest = || { if have_outer_deref { // Only the last field projection gets a destination @@ -430,6 +452,7 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { self.loc(location, location, project_fn) .arg_var(inner_deref_base) .arg_addr_of(outer_deref_base.clone()) + .arg_var(proj_idx) .source(&inner_deref_op) .dest_from(dest) .add_to(self); @@ -800,7 +823,8 @@ fn instrument_body<'a, 'tcx>( // collect instrumentation points let points = { - let mut collector = CollectInstrumentationPoints::new(tcx, hooks, body, local_to_address); + let mut collector = + CollectInstrumentationPoints::new(tcx, hooks, body, local_to_address, state); collector.visit_body(body); collector.into_instrumentation_points() }; diff --git a/dynamic_instrumentation/src/into_operand.rs b/dynamic_instrumentation/src/into_operand.rs index 49c9527f5e..1ddfe92172 100644 --- a/dynamic_instrumentation/src/into_operand.rs +++ b/dynamic_instrumentation/src/into_operand.rs @@ -31,6 +31,20 @@ impl<'tcx> IntoOperand<'tcx> for u32 { } } +impl<'tcx> IntoOperand<'tcx> for usize { + fn op(self, tcx: TyCtxt<'tcx>) -> Operand<'tcx> { + Operand::Constant(Box::new(Constant { + span: DUMMY_SP, + user_ty: None, + literal: ConstantKind::Ty(ty::Const::from_bits( + tcx, + self.try_into().unwrap(), + ParamEnv::empty().and(tcx.types.usize), + )), + })) + } +} + impl<'tcx> IntoOperand<'tcx> for Local { fn op(self, tcx: TyCtxt<'tcx>) -> Operand<'tcx> { Place::from(self).op(tcx) diff --git a/dynamic_instrumentation/src/point/mod.rs b/dynamic_instrumentation/src/point/mod.rs index 1b3a069c3f..f15398ab09 100644 --- a/dynamic_instrumentation/src/point/mod.rs +++ b/dynamic_instrumentation/src/point/mod.rs @@ -112,6 +112,10 @@ impl<'tcx> RewriteAddressTakenLocals<'tcx> { } } +pub trait ProjectionSet { + fn add_proj(&self, proj: Vec) -> usize; +} + pub struct CollectInstrumentationPoints<'a, 'tcx: 'a> { tcx: TyCtxt<'tcx>, hooks: Hooks<'tcx>, @@ -119,6 +123,7 @@ pub struct CollectInstrumentationPoints<'a, 'tcx: 'a> { pub instrumentation_points: Vec>, assignment: Option<(Place<'tcx>, Rvalue<'tcx>)>, pub addr_taken_local_addresses: IndexMap, + pub projections: &'a dyn ProjectionSet, } impl<'a, 'tcx: 'a> CollectInstrumentationPoints<'a, 'tcx> { @@ -127,6 +132,7 @@ impl<'a, 'tcx: 'a> CollectInstrumentationPoints<'a, 'tcx> { hooks: Hooks<'tcx>, body: &'a Body<'tcx>, addr_taken_local_addresses: IndexMap, + projections: &'a dyn ProjectionSet, ) -> Self { Self { tcx, @@ -135,6 +141,7 @@ impl<'a, 'tcx: 'a> CollectInstrumentationPoints<'a, 'tcx> { instrumentation_points: Default::default(), assignment: Default::default(), addr_taken_local_addresses, + projections, } } diff --git a/pdg/src/builder.rs b/pdg/src/builder.rs index d14ca1334e..c290b46f87 100644 --- a/pdg/src/builder.rs +++ b/pdg/src/builder.rs @@ -70,7 +70,7 @@ impl EventKindExt for EventKind { Realloc { .. } => NodeKind::Alloc(1), Free { .. } => NodeKind::Free, CopyPtr(..) | CopyRef => NodeKind::Copy, - Project(base_ptr, new_ptr) => NodeKind::Project(new_ptr - base_ptr), + Project(base_ptr, new_ptr, idx) => NodeKind::Project(new_ptr - base_ptr, idx), LoadAddr(..) => NodeKind::LoadAddr, StoreAddr(..) => NodeKind::StoreAddr, StoreAddrTaken(..) => NodeKind::StoreAddr, diff --git a/pdg/src/graph.rs b/pdg/src/graph.rs index 01b9fa3ff6..e0feb4edcd 100644 --- a/pdg/src/graph.rs +++ b/pdg/src/graph.rs @@ -25,7 +25,7 @@ pub enum NodeKind { /// [`Field`] projection. /// /// Used for operations like `_2 = &(*_1).0`. - Project(usize), + Project(usize, usize), /// Pointer arithmetic. /// @@ -119,7 +119,7 @@ impl Display for NodeKind { use NodeKind::*; match self { Copy => write!(f, "copy"), - Project(offset) => write!(f, "project.{offset}"), + Project(offset, idx) => write!(f, "project.{idx}@{offset}"), Offset(offset) => write!(f, "offset[{offset}]"), AddrOfLocal(local) => write!(f, "&{local:?}"), _AddrOfStatic(static_) => write!(f, "&'static {static_:?}"), diff --git a/pdg/src/info.rs b/pdg/src/info.rs index 1a247acfba..0538b7604d 100644 --- a/pdg/src/info.rs +++ b/pdg/src/info.rs @@ -113,7 +113,7 @@ fn collect_children(g: &Graph) -> HashMap)>> { .rev() .filter_map(|(child, child_node)| Some((child_node.source?, child, child_node))) { - if let NodeKind::Project(f) = child_node.kind { + if let NodeKind::Project(_, f) = child_node.kind { let my_children = children .remove(&child) @@ -256,8 +256,8 @@ mod test { mk_node(g, NodeKind::StoreAddr, Some(source)) } - fn mk_project(g: &mut Graph, source: NodeId, field: impl Into) -> NodeId { - mk_node(g, NodeKind::Project(field.into()), Some(source)) + fn mk_project(g: &mut Graph, source: NodeId, field: impl Into, idx: usize) -> NodeId { + mk_node(g, NodeKind::Project(field.into(), idx), Some(source)) } fn mk_offset(g: &mut Graph, source: NodeId, i: isize) -> NodeId { @@ -486,10 +486,10 @@ mod test { // let mut a = Point { x: 0, y: 0 }; let a = mk_addr_of_local(&mut g, 0_u32); // let b = &mut a.x; - let b11 = mk_project(&mut g, a, 0_usize); + let b11 = mk_project(&mut g, a, 0_usize, 0); let b1 = mk_copy(&mut g, b11); // let c = &mut a.y; - let c11 = mk_project(&mut g, a, 1_usize); + let c11 = mk_project(&mut g, a, 1_usize, 1); let c1 = mk_copy(&mut g, c11); // *b = 1; let b2 = mk_store_addr(&mut g, b1); @@ -536,17 +536,17 @@ mod test { // let j = &mut a; let j = mk_copy(&mut g, a); // let b = &mut j.x; - let b11 = mk_project(&mut g, j, 0_usize); + let b11 = mk_project(&mut g, j, 0_usize, 0); let b1 = mk_copy(&mut g, b11); // let c = &mut j.x; - let c11 = mk_project(&mut g, j, 0_usize); + let c11 = mk_project(&mut g, j, 0_usize, 0); let c1 = mk_copy(&mut g, c11); // *b = 1; let b2 = mk_store_addr(&mut g, b1); // *c = 2; let c2 = mk_store_addr(&mut g, c1); // *(a.y) = 3; - let d1 = mk_project(&mut g, a, 1_usize); + let d1 = mk_project(&mut g, a, 1_usize, 1); let d2 = mk_store_addr(&mut g, d1); let pdg = build_pdg(g); @@ -585,7 +585,7 @@ mod test { // let b = &mut a; let b1 = mk_copy(&mut g, a); // let c = &mut a.y; - let c11 = mk_project(&mut g, a, 1_usize); + let c11 = mk_project(&mut g, a, 1_usize, 0); let c1 = mk_copy(&mut g, c11); // *c = 2; let c2 = mk_store_addr(&mut g, c1); @@ -631,10 +631,10 @@ mod test { // let b = &mut a; let b1 = mk_copy(&mut g, a); // let c = &mut b.y; - let c1 = mk_project(&mut g, a, 1_usize); + let c1 = mk_project(&mut g, a, 1_usize, 0); let c2 = mk_copy(&mut g, c1); // let bb = &mut b.y; - let bb = mk_project(&mut g, b1, 1_usize); + let bb = mk_project(&mut g, b1, 1_usize, 0); let bb1 = mk_copy(&mut g, bb); // *c = 2; let c3 = mk_store_addr(&mut g, c2); @@ -676,14 +676,14 @@ mod test { // let mut a = ColorPoint { x: 0, y: 0, z: Color { r: 100, g: 100, b: 100 } }; let a = mk_addr_of_local(&mut g, 0_u32); // let b = &mut a.x; - let bb1 = mk_project(&mut g, a, x); + let bb1 = mk_project(&mut g, a, x, 0); let b1 = mk_copy(&mut g, bb1); // let c = &mut a.y; - let cc1 = mk_project(&mut g, a, y); + let cc1 = mk_project(&mut g, a, y, 1); let c1 = mk_copy(&mut g, cc1); // a.z.r = 200; - let x1 = mk_project(&mut g, a, z); - let x2 = mk_project(&mut g, x1, red); + let x1 = mk_project(&mut g, a, z, 2); + let x2 = mk_project(&mut g, x1, red, 0); let x3 = mk_store_addr(&mut g, x2); // *b = 4; let b2 = mk_store_addr(&mut g, b1); @@ -694,19 +694,19 @@ mod test { // *d = ColorPoint { x: 0, y: 0, z: Color { r: 20, g: 200, b: 20 } }; let d2 = mk_store_addr(&mut g, d1); // let e = &mut a.z; - let ee = mk_project(&mut g, a, z); + let ee = mk_project(&mut g, a, z, 2); let e = mk_copy(&mut g, ee); // let f = &mut e.g; - let ff1 = mk_project(&mut g, e, green); + let ff1 = mk_project(&mut g, e, green, 1); let f1 = mk_copy(&mut g, ff1); // let g = &mut e.g; - let ggg = mk_project(&mut g, e, green); + let ggg = mk_project(&mut g, e, green, 1); let gg = mk_copy(&mut g, ggg); // *f = 3; let f2 = mk_store_addr(&mut g, f1); // a.z.r = 100; - let x4 = mk_project(&mut g, a, z); - let x5 = mk_project(&mut g, x4, green); + let x4 = mk_project(&mut g, a, z, 2); + let x5 = mk_project(&mut g, x4, green, 1); let x6 = mk_store_addr(&mut g, x5); let pdg = build_pdg(g); @@ -759,10 +759,10 @@ mod test { // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0; - let x1 = mk_project(&mut g, a, 0_usize); + let x1 = mk_project(&mut g, a, 0_usize, 0); let x2 = mk_copy(&mut g, x1); // let y = &mut a.1; - let y1 = mk_project(&mut g, a, 1_usize); + let y1 = mk_project(&mut g, a, 1_usize, 1); let y2 = mk_copy(&mut g, y1); // *x = 1; let x3 = mk_store_addr(&mut g, x2); @@ -817,12 +817,12 @@ mod test { // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.1.0; - let x1 = mk_project(&mut g, a, 1_usize); - let x2 = mk_project(&mut g, x1, 0_usize); + let x1 = mk_project(&mut g, a, 1_usize, 0); + let x2 = mk_project(&mut g, x1, 0_usize, 1); let x3 = mk_copy(&mut g, x2); // let y = &mut a.1.1; - let y1 = mk_project(&mut g, a, 1_usize); - let y2 = mk_project(&mut g, y1, 1_usize); + let y1 = mk_project(&mut g, a, 1_usize, 0); + let y2 = mk_project(&mut g, y1, 1_usize, 0); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); @@ -871,16 +871,16 @@ mod test { //let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); //let mut x = &mut a.1; - let x1 = mk_project(&mut g, a, 1_usize); + let x1 = mk_project(&mut g, a, 1_usize, 0); let x2 = mk_copy(&mut g, x1); //let mut y = &mut a.1; - let y1 = mk_project(&mut g, a, 1_usize); + let y1 = mk_project(&mut g, a, 1_usize, 0); let y2 = mk_copy(&mut g, y1); // *(x.0) = 4; - let x3 = mk_project(&mut g, x2, 0_usize); + let x3 = mk_project(&mut g, x2, 0_usize, 1); let x4 = mk_store_addr(&mut g, x3); // *(y.1) = 2; - let y3 = mk_project(&mut g, y2, 1_usize); + let y3 = mk_project(&mut g, y2, 1_usize, 0); let y4 = mk_store_addr(&mut g, y3); let pdg = build_pdg(g); @@ -925,12 +925,12 @@ mod test { // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.1.0; - let x1 = mk_project(&mut g, a, 1_usize); - let x2 = mk_project(&mut g, x1, 0_usize); + let x1 = mk_project(&mut g, a, 1_usize, 0); + let x2 = mk_project(&mut g, x1, 0_usize, 1); let x3 = mk_copy(&mut g, x2); // let y = &mut a.1.0; - let y1 = mk_project(&mut g, a, 1_usize); - let y2 = mk_project(&mut g, y1, 0_usize); + let y1 = mk_project(&mut g, a, 1_usize, 0); + let y2 = mk_project(&mut g, y1, 0_usize, 1); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); @@ -987,11 +987,11 @@ mod test { // let mut a = ([1, 2], [3, 4]); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0[0]; - let x1 = mk_project(&mut g, a, 1_usize); + let x1 = mk_project(&mut g, a, 1_usize, 0); let x2 = mk_offset(&mut g, x1, 0); let x3 = mk_copy(&mut g, x2); // let y = &mut a.0[1]; - let y1 = mk_project(&mut g, a, 1_usize); + let y1 = mk_project(&mut g, a, 1_usize, 0); let y2 = mk_offset(&mut g, y1, 1); let y3 = mk_copy(&mut g, y2); // *x = 1; @@ -1049,11 +1049,11 @@ mod test { // let mut a = ([1, 2], [3, 4]); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0[0]; - let x1 = mk_project(&mut g, a, 0_usize); + let x1 = mk_project(&mut g, a, 0_usize, 0); let x2 = mk_offset(&mut g, x1, 0); let x3 = mk_copy(&mut g, x2); // let y = &mut a.1[0]; - let y1 = mk_project(&mut g, a, 1_usize); + let y1 = mk_project(&mut g, a, 1_usize, 1); let y2 = mk_offset(&mut g, y1, 0); let y3 = mk_copy(&mut g, y2); // *x = 1; @@ -1121,11 +1121,11 @@ mod test { let p = mk_addr_of_local(&mut g, 0_u32); // let x = &mut (*p)[0].0; let x1 = mk_offset(&mut g, p, 0); - let x2 = mk_project(&mut g, x1, 0_usize); + let x2 = mk_project(&mut g, x1, 0_usize, 0); let x3 = mk_copy(&mut g, x2); // let y = &mut (*p)[0].1; let y1 = mk_offset(&mut g, p, 0); - let y2 = mk_project(&mut g, y1, 1_usize); + let y2 = mk_project(&mut g, y1, 1_usize, 1); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); From 152c3aee857eda82b746fc18ad266cef04698957 Mon Sep 17 00:00:00 2001 From: Andrei Homescu Date: Thu, 13 Jun 2024 00:41:07 -0700 Subject: [PATCH 3/4] Build PDG without tracking assignments The event assignment-based PDG construction steps were giving incorrect results for indirect accesses, so remove them completely. --- pdg/src/builder.rs | 61 +++++++++------------------------------------- 1 file changed, 12 insertions(+), 49 deletions(-) diff --git a/pdg/src/builder.rs b/pdg/src/builder.rs index c290b46f87..467ceff299 100644 --- a/pdg/src/builder.rs +++ b/pdg/src/builder.rs @@ -122,7 +122,7 @@ fn update_provenance( Realloc { new_ptr, .. } => { provenances.insert(new_ptr, mapping); } - Offset(_, _, new_ptr) => { + Offset(_, _, new_ptr) | Project(_, new_ptr, _) => { provenances.insert(new_ptr, mapping); } CopyRef => { @@ -151,7 +151,7 @@ pub fn add_node( let node_kind = event.kind.to_node_kind(func.id, address_taken)?; let this_id = func.id; - let (src_fn, dest_fn) = match event_metadata.transfer_kind { + let (_src_fn, dest_fn) = match event_metadata.transfer_kind { TransferKind::None => (this_id, this_id), TransferKind::Arg(id) => (this_id, id), TransferKind::Ret(id) => (id, this_id), @@ -173,37 +173,22 @@ pub fn add_node( .iter() .rposition(|n| { if let (Some(d), Some(s)) = (&n.dest, &event_metadata.source) { - d == s + // TODO: Ignore direct assignments with projections for now, + // e.g., `_1.0 = _2;`. We should later add support for + // assignments to sub-fields, e.g. + // ``` + // _1 = _2; + // _1.0 = _3; + // _1 = _4; + // ``` + d == s && s.projection.is_empty() } else { false } }) .map(|nid| (gid, NodeId::from(nid))) }); - - let source = direct_source.or_else(|| { - event_metadata.source.as_ref().and_then(|src| { - let latest_assignment = graphs.latest_assignment.get(&(src_fn, src.local)).cloned(); - if !src.projection.is_empty() { - if let Some((gid, _)) = latest_assignment { - if let Some((nid, n)) = graphs.graphs[gid].nodes.iter_enumerated().rev().next() - { - if let NodeKind::Project(..) = n.kind { - return Some((gid, nid)); - } - } - } - } - - if !matches!(event.kind, EventKind::AddrOfLocal(..)) && src.projection.is_empty() { - latest_assignment - } else if let EventKind::Project(..) = event.kind { - latest_assignment - } else { - provenance - } - }) - }); + let source = direct_source.or(provenance); let function = Func { id: dest_fn, @@ -224,8 +209,6 @@ pub fn add_node( }; let graph_id = source - .or(direct_source) - .or(provenance) .and_then(|p| parent(&node_kind, p)) .map(|(gid, _)| gid) .unwrap_or_else(|| graphs.graphs.push(Graph::new())); @@ -238,26 +221,6 @@ pub fn add_node( (graph_id, node_id), ); - if let Some(dest) = &event_metadata.destination { - let unique_place = (dest_fn, dest.local); - let last_setting = (graph_id, node_id); - - if let Some(last @ (last_gid, last_nid)) = - graphs.latest_assignment.insert(unique_place, last_setting) - { - if !dest.projection.is_empty() - && graphs.graphs[last_gid].nodes[last_nid] - .dest - .as_ref() - .unwrap() - .projection - .is_empty() - { - graphs.latest_assignment.insert(unique_place, last); - } - } - } - Some(node_id) } From 9b94bad292e29221e889b5598e6169f02ee5f8de Mon Sep 17 00:00:00 2001 From: Andrei Homescu Date: Wed, 24 Jul 2024 17:43:58 -0700 Subject: [PATCH 4/4] Update PDG snapshots --- ...nalysis_tests_misc_pdg_snapshot_debug.snap | 891 +++++++++--------- ...lysis_tests_misc_pdg_snapshot_release.snap | 891 +++++++++--------- 2 files changed, 884 insertions(+), 898 deletions(-) diff --git a/pdg/src/snapshots/c2rust_pdg__tests__analysis_tests_misc_pdg_snapshot_debug.snap b/pdg/src/snapshots/c2rust_pdg__tests__analysis_tests_misc_pdg_snapshot_debug.snap index f63a2ed663..b7dfab1d78 100644 --- a/pdg/src/snapshots/c2rust_pdg__tests__analysis_tests_misc_pdg_snapshot_debug.snap +++ b/pdg/src/snapshots/c2rust_pdg__tests__analysis_tests_misc_pdg_snapshot_debug.snap @@ -1,5 +1,6 @@ --- source: pdg/src/main.rs +assertion_line: 376 expression: pdg --- g { @@ -19,13 +20,13 @@ nodes_that_need_write = [] g { n[0]: copy _ => _14 @ bb6[4]: fn main; _14 = null_mut(); n[1]: copy n[0] => _1 @ bb0[0]: fn once; _13 = once(move _14); - n[2]: int_to_ptr _ => _17 @ bb4[29]: fn simple; _17 = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[3]: value.store _ => _20.* @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); - n[4]: value.store _ => _17.* @ bb8[4]: fn fdevent_unregister; (*_17) = const 0_usize as *mut pointers::fdnode_st (PointerFromExposedAddress); - n[5]: int_to_ptr _ => _2 @ bb0[2]: fn test_ref_field; _2 = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[6]: int_to_ptr _ => _5 @ bb0[8]: fn test_ref_field; _5 = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[7]: int_to_ptr _ => _51 @ bb36[3]: fn main_0; _51 = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[8]: value.store _ => _3.*.2 @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[2]: int_to_ptr n[0] => _17 @ bb4[29]: fn simple; _17 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[3]: value.store n[0] => _20.* @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); + n[4]: value.store n[0] => _17.* @ bb8[4]: fn fdevent_unregister; (*_17) = const 0_usize as *mut pointers::fdnode_st (PointerFromExposedAddress); + n[5]: int_to_ptr n[0] => _2 @ bb0[2]: fn test_ref_field; _2 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[6]: int_to_ptr n[0] => _5 @ bb0[8]: fn test_ref_field; _5 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[7]: int_to_ptr n[0] => _51 @ bb36[3]: fn main_0; _51 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[8]: value.store n[0] => _3.*.2 @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); } nodes_that_need_write = [] @@ -44,75 +45,69 @@ g { nodes_that_need_write = [] g { - n[0]: alloc _ => _2 @ bb1[2]: fn simple; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn simple; _1 = move _2 as *mut pointers::S (Misc); - n[2]: copy n[1] => _5 @ bb2[5]: fn simple; _5 = _1; - n[3]: field.0 n[1] => _10 @ bb4[5]: fn simple; _10 = &raw const ((*_1).0: i32); - n[4]: copy n[2] => _24 @ bb5[5]: fn simple; _24 = _5; - n[5]: copy n[4] => _23 @ bb5[6]: fn simple; _23 = move _24 as *mut libc::c_void (Misc); - n[6]: free n[5] => _22 @ bb5[8]: fn simple; _22 = free(move _23); + n[0]: alloc _ => _2 @ bb1[2]: fn simple; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn simple; _1 = move _2 as *mut pointers::S (Misc); + n[2]: copy n[1] => _5 @ bb2[5]: fn simple; _5 = _1; + n[3]: project.0@0 n[1] => _10 @ bb4[5]: fn simple; _10 = &raw const ((*_1).0: i32); + n[4]: copy n[2] => _24 @ bb5[5]: fn simple; _24 = _5; + n[5]: copy n[4] => _23 @ bb5[6]: fn simple; _23 = move _24 as *mut libc::c_void (Misc); + n[6]: free n[5] => _22 @ bb5[8]: fn simple; _22 = free(move _23); } nodes_that_need_write = [] g { - n[0]: alloc _ => _7 @ bb3[2]: fn simple; _7 = malloc(move _8); - n[1]: copy n[0] => _6 @ bb4[1]: fn simple; _6 = move _7 as *mut pointers::S (Misc); - n[2]: copy n[1] => _11 @ bb4[8]: fn simple; _11 = _6; - n[3]: copy n[2] => _1 @ bb4[9]: fn simple; _1 = move _11; - n[4]: field.0 n[3] => _ @ bb4[11]: fn simple; ((*_1).0: i32) = const 10_i32; - n[5]: addr.store n[4] => _ @ bb4[11]: fn simple; ((*_1).0: i32) = const 10_i32; - n[6]: field.0 n[3] => _12 @ bb4[13]: fn simple; _12 = ((*_1).0: i32); - n[7]: addr.load n[6] => _ @ bb4[13]: fn simple; _12 = ((*_1).0: i32); - n[8]: field.0 n[1] => _ @ bb4[14]: fn simple; ((*_6).0: i32) = move _12; - n[9]: addr.store n[8] => _ @ bb4[14]: fn simple; ((*_6).0: i32) = move _12; - n[10]: field.1 n[3] => _ @ bb4[16]: fn simple; ((*_1).1: u64) = const 9_u64; - n[11]: addr.store n[10] => _ @ bb4[16]: fn simple; ((*_1).1: u64) = const 9_u64; - n[12]: field.0 n[3] => _13 @ bb4[18]: fn simple; _13 = ((*_1).0: i32); - n[13]: addr.load n[12] => _ @ bb4[18]: fn simple; _13 = ((*_1).0: i32); - n[14]: field.1 n[3] => _14 @ bb4[21]: fn simple; _14 = &raw const ((*_1).1: u64); - n[15]: copy n[14] => _14 @ bb4[21]: fn simple; _14 = &raw const ((*_1).1: u64); - n[16]: copy n[3] => _15 @ bb4[24]: fn simple; _15 = &raw const (*_1); - n[17]: field.2 n[3] => _ @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; - n[18]: addr.store n[17] => _ @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; - n[19]: value.store n[16] => _1.*.2 @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; - n[20]: field.3 n[1] => _ @ bb4[32]: fn simple; ((*_6).3: pointers::T) = move _16; - n[21]: addr.store n[20] => _ @ bb4[32]: fn simple; ((*_6).3: pointers::T) = move _16; - n[22]: addr.load n[1] => _ @ bb4[35]: fn simple; _18 = (*_6); - n[23]: addr.store n[3] => _ @ bb4[39]: fn simple; (*_1) = move _19; - n[24]: copy n[3] => _21 @ bb4[43]: fn simple; _21 = _1; - n[25]: copy n[24] => _2 @ bb0[0]: fn recur; _20 = recur(const 3_i32, move _21); - n[26]: copy n[25] => _13 @ bb8[3]: fn recur; _13 = _2; - n[27]: copy n[26] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _13); - n[28]: copy n[27] => _13 @ bb8[3]: fn recur; _13 = _2; - n[29]: copy n[28] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _13); - n[30]: copy n[29] => _13 @ bb8[3]: fn recur; _13 = _2; - n[31]: copy n[30] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _13); - n[32]: copy n[31] => _8 @ bb1[2]: fn recur; _8 = _2; - n[33]: copy n[32] => _7 @ bb1[3]: fn recur; _7 = move _8 as *mut libc::c_void (Misc); - n[34]: free n[33] => _0 @ bb1[5]: fn recur; _0 = free(move _7); - n[35]: copy n[31] => _14 @ bb9[4]: fn recur; _14 = _2; - n[36]: copy n[31] => _14 @ bb9[4]: fn recur; _14 = _2; - n[37]: copy n[31] => _14 @ bb9[4]: fn recur; _14 = _2; -} -nodes_that_need_write = [23, 21, 20, 18, 17, 11, 10, 9, 8, 5, 4, 3, 2, 1, 0] - -g { - n[0]: &_1 _ => _ @ bb4[5]: fn simple; _10 = &raw const ((*_1).0: i32); + n[0]: alloc _ => _7 @ bb3[2]: fn simple; _7 = malloc(move _8); + n[1]: copy n[0] => _6 @ bb4[1]: fn simple; _6 = move _7 as *mut pointers::S (Misc); + n[2]: copy n[1] => _11 @ bb4[8]: fn simple; _11 = _6; + n[3]: copy n[2] => _1 @ bb4[9]: fn simple; _1 = move _11; + n[4]: project.0@0 n[3] => _ @ bb4[11]: fn simple; ((*_1).0: i32) = const 10_i32; + n[5]: addr.store n[3] => _ @ bb4[11]: fn simple; ((*_1).0: i32) = const 10_i32; + n[6]: project.0@0 n[3] => _ @ bb4[13]: fn simple; _12 = ((*_1).0: i32); + n[7]: addr.load n[3] => _ @ bb4[13]: fn simple; _12 = ((*_1).0: i32); + n[8]: project.0@0 n[1] => _ @ bb4[14]: fn simple; ((*_6).0: i32) = move _12; + n[9]: addr.store n[1] => _ @ bb4[14]: fn simple; ((*_6).0: i32) = move _12; + n[10]: project.1@8 n[3] => _ @ bb4[16]: fn simple; ((*_1).1: u64) = const 9_u64; + n[11]: addr.store n[3] => _ @ bb4[16]: fn simple; ((*_1).1: u64) = const 9_u64; + n[12]: project.0@0 n[3] => _ @ bb4[18]: fn simple; _13 = ((*_1).0: i32); + n[13]: addr.load n[3] => _ @ bb4[18]: fn simple; _13 = ((*_1).0: i32); + n[14]: project.1@8 n[3] => _14 @ bb4[21]: fn simple; _14 = &raw const ((*_1).1: u64); + n[15]: copy n[3] => _15 @ bb4[24]: fn simple; _15 = &raw const (*_1); + n[16]: project.2@16 n[3] => _ @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; + n[17]: addr.store n[3] => _ @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; + n[18]: value.store n[15] => _1.*.2 @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; + n[19]: project.3@24 n[1] => _ @ bb4[32]: fn simple; ((*_6).3: pointers::T) = move _16; + n[20]: addr.store n[1] => _ @ bb4[32]: fn simple; ((*_6).3: pointers::T) = move _16; + n[21]: addr.load n[1] => _ @ bb4[35]: fn simple; _18 = (*_6); + n[22]: addr.store n[3] => _ @ bb4[39]: fn simple; (*_1) = move _19; + n[23]: copy n[3] => _21 @ bb4[43]: fn simple; _21 = _1; + n[24]: copy n[23] => _2 @ bb0[0]: fn recur; _20 = recur(const 3_i32, move _21); + n[25]: copy n[24] => _13 @ bb8[3]: fn recur; _13 = _2; + n[26]: copy n[25] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _13); + n[27]: copy n[26] => _13 @ bb8[3]: fn recur; _13 = _2; + n[28]: copy n[27] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _13); + n[29]: copy n[28] => _13 @ bb8[3]: fn recur; _13 = _2; + n[30]: copy n[29] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _13); + n[31]: copy n[30] => _8 @ bb1[2]: fn recur; _8 = _2; + n[32]: copy n[31] => _7 @ bb1[3]: fn recur; _7 = move _8 as *mut libc::c_void (Misc); + n[33]: free n[32] => _0 @ bb1[5]: fn recur; _0 = free(move _7); + n[34]: copy n[30] => _14 @ bb9[4]: fn recur; _14 = _2; + n[35]: copy n[30] => _14 @ bb9[4]: fn recur; _14 = _2; + n[36]: copy n[30] => _14 @ bb9[4]: fn recur; _14 = _2; +} +nodes_that_need_write = [22, 20, 17, 11, 9, 5, 3, 2, 1, 0] + +g { + n[0]: alloc _ => _2 @ bb1[2]: fn exercise_allocator; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn exercise_allocator; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[5]: fn exercise_allocator; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[5]: fn exercise_allocator; ((*_1).0: i32) = const 10_i32; + n[4]: project.0@0 n[1] => _ @ bb2[18]: fn exercise_allocator; _10 = ((*_1).0: i32); + n[5]: addr.load n[1] => _ @ bb2[18]: fn exercise_allocator; _10 = ((*_1).0: i32); + n[6]: copy n[1] => _13 @ bb3[7]: fn exercise_allocator; _13 = _1; + n[7]: copy n[6] => _12 @ bb3[8]: fn exercise_allocator; _12 = move _13 as *mut libc::c_void (Misc); + n[8]: free n[7] => _11 @ bb5[2]: fn exercise_allocator; _11 = realloc(move _12, move _14); } -nodes_that_need_write = [] - -g { - n[0]: alloc _ => _2 @ bb1[2]: fn exercise_allocator; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn exercise_allocator; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[5]: fn exercise_allocator; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[5]: fn exercise_allocator; ((*_1).0: i32) = const 10_i32; - n[4]: field.0 n[1] => _10 @ bb2[18]: fn exercise_allocator; _10 = ((*_1).0: i32); - n[5]: addr.load n[4] => _ @ bb2[18]: fn exercise_allocator; _10 = ((*_1).0: i32); - n[6]: copy n[1] => _13 @ bb3[7]: fn exercise_allocator; _13 = _1; - n[7]: copy n[6] => _12 @ bb3[8]: fn exercise_allocator; _12 = move _13 as *mut libc::c_void (Misc); - n[8]: free n[7] => _11 @ bb5[2]: fn exercise_allocator; _11 = realloc(move _12, move _14); -} -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { n[0]: copy _ => _9 @ bb2[11]: fn exercise_allocator; _9 = const b"%i\n\x00"; @@ -120,72 +115,72 @@ g { n[2]: copy n[1] => _7 @ bb2[13]: fn exercise_allocator; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); n[3]: copy n[2] => _6 @ bb2[15]: fn exercise_allocator; _6 = move _7 as *const i8 (Misc); n[4]: copy n[3] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); - n[5]: copy _ => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; + n[5]: copy n[0] => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; n[6]: copy n[5] => _30 @ bb11[6]: fn exercise_allocator; _30 = &raw const (*_31); n[7]: copy n[6] => _29 @ bb11[7]: fn exercise_allocator; _29 = move _30 as *const u8 (Pointer(ArrayToPointer)); n[8]: copy n[7] => _28 @ bb11[9]: fn exercise_allocator; _28 = move _29 as *const i8 (Misc); n[9]: copy n[8] => _1 @ bb0[0]: fn printf; _27 = printf(move _28, move _32); - n[10]: copy _ => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; + n[10]: copy n[0] => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; n[11]: copy n[10] => _30 @ bb11[6]: fn exercise_allocator; _30 = &raw const (*_31); n[12]: copy n[11] => _29 @ bb11[7]: fn exercise_allocator; _29 = move _30 as *const u8 (Pointer(ArrayToPointer)); n[13]: copy n[12] => _28 @ bb11[9]: fn exercise_allocator; _28 = move _29 as *const i8 (Misc); n[14]: copy n[13] => _1 @ bb0[0]: fn printf; _27 = printf(move _28, move _32); - n[15]: copy _ => _61 @ bb29[5]: fn exercise_allocator; _61 = const b"%i\n\x00"; + n[15]: copy n[0] => _61 @ bb29[5]: fn exercise_allocator; _61 = const b"%i\n\x00"; n[16]: copy n[15] => _60 @ bb29[6]: fn exercise_allocator; _60 = &raw const (*_61); n[17]: copy n[16] => _59 @ bb29[7]: fn exercise_allocator; _59 = move _60 as *const u8 (Pointer(ArrayToPointer)); n[18]: copy n[17] => _58 @ bb29[9]: fn exercise_allocator; _58 = move _59 as *const i8 (Misc); n[19]: copy n[18] => _1 @ bb0[0]: fn printf; _57 = printf(move _58, move _62); - n[20]: copy _ => _61 @ bb29[5]: fn exercise_allocator; _61 = const b"%i\n\x00"; + n[20]: copy n[0] => _61 @ bb29[5]: fn exercise_allocator; _61 = const b"%i\n\x00"; n[21]: copy n[20] => _60 @ bb29[6]: fn exercise_allocator; _60 = &raw const (*_61); n[22]: copy n[21] => _59 @ bb29[7]: fn exercise_allocator; _59 = move _60 as *const u8 (Pointer(ArrayToPointer)); n[23]: copy n[22] => _58 @ bb29[9]: fn exercise_allocator; _58 = move _59 as *const i8 (Misc); n[24]: copy n[23] => _1 @ bb0[0]: fn printf; _57 = printf(move _58, move _62); - n[25]: copy _ => _61 @ bb29[5]: fn exercise_allocator; _61 = const b"%i\n\x00"; + n[25]: copy n[0] => _61 @ bb29[5]: fn exercise_allocator; _61 = const b"%i\n\x00"; n[26]: copy n[25] => _60 @ bb29[6]: fn exercise_allocator; _60 = &raw const (*_61); n[27]: copy n[26] => _59 @ bb29[7]: fn exercise_allocator; _59 = move _60 as *const u8 (Pointer(ArrayToPointer)); n[28]: copy n[27] => _58 @ bb29[9]: fn exercise_allocator; _58 = move _59 as *const i8 (Misc); n[29]: copy n[28] => _1 @ bb0[0]: fn printf; _57 = printf(move _58, move _62); - n[30]: copy _ => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; + n[30]: copy n[0] => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; n[31]: copy n[30] => _93 @ bb49[6]: fn exercise_allocator; _93 = &raw const (*_94); n[32]: copy n[31] => _92 @ bb49[7]: fn exercise_allocator; _92 = move _93 as *const u8 (Pointer(ArrayToPointer)); n[33]: copy n[32] => _91 @ bb49[9]: fn exercise_allocator; _91 = move _92 as *const i8 (Misc); n[34]: copy n[33] => _1 @ bb0[0]: fn printf; _90 = printf(move _91, move _95); - n[35]: copy _ => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; + n[35]: copy n[0] => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; n[36]: copy n[35] => _93 @ bb49[6]: fn exercise_allocator; _93 = &raw const (*_94); n[37]: copy n[36] => _92 @ bb49[7]: fn exercise_allocator; _92 = move _93 as *const u8 (Pointer(ArrayToPointer)); n[38]: copy n[37] => _91 @ bb49[9]: fn exercise_allocator; _91 = move _92 as *const i8 (Misc); n[39]: copy n[38] => _1 @ bb0[0]: fn printf; _90 = printf(move _91, move _95); - n[40]: copy _ => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; + n[40]: copy n[0] => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; n[41]: copy n[40] => _93 @ bb49[6]: fn exercise_allocator; _93 = &raw const (*_94); n[42]: copy n[41] => _92 @ bb49[7]: fn exercise_allocator; _92 = move _93 as *const u8 (Pointer(ArrayToPointer)); n[43]: copy n[42] => _91 @ bb49[9]: fn exercise_allocator; _91 = move _92 as *const i8 (Misc); n[44]: copy n[43] => _1 @ bb0[0]: fn printf; _90 = printf(move _91, move _95); - n[45]: copy _ => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; + n[45]: copy n[0] => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; n[46]: copy n[45] => _93 @ bb49[6]: fn exercise_allocator; _93 = &raw const (*_94); n[47]: copy n[46] => _92 @ bb49[7]: fn exercise_allocator; _92 = move _93 as *const u8 (Pointer(ArrayToPointer)); n[48]: copy n[47] => _91 @ bb49[9]: fn exercise_allocator; _91 = move _92 as *const i8 (Misc); n[49]: copy n[48] => _1 @ bb0[0]: fn printf; _90 = printf(move _91, move _95); - n[50]: copy _ => _9 @ bb2[11]: fn simple_analysis; _9 = const b"%i\n\x00"; + n[50]: copy n[0] => _9 @ bb2[11]: fn simple_analysis; _9 = const b"%i\n\x00"; n[51]: copy n[50] => _8 @ bb2[12]: fn simple_analysis; _8 = &raw const (*_9); n[52]: copy n[51] => _7 @ bb2[13]: fn simple_analysis; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); n[53]: copy n[52] => _6 @ bb2[15]: fn simple_analysis; _6 = move _7 as *const i8 (Misc); n[54]: copy n[53] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); - n[55]: copy _ => _6 @ bb0[5]: fn analysis2_helper; _6 = const b"%i\n\x00"; + n[55]: copy n[0] => _6 @ bb0[5]: fn analysis2_helper; _6 = const b"%i\n\x00"; n[56]: copy n[55] => _5 @ bb0[6]: fn analysis2_helper; _5 = &raw const (*_6); n[57]: copy n[56] => _4 @ bb0[7]: fn analysis2_helper; _4 = move _5 as *const u8 (Pointer(ArrayToPointer)); n[58]: copy n[57] => _3 @ bb0[9]: fn analysis2_helper; _3 = move _4 as *const i8 (Misc); n[59]: copy n[58] => _1 @ bb0[0]: fn printf; _2 = printf(move _3, move _7); - n[60]: copy _ => _9 @ bb2[11]: fn inter_function_analysis; _9 = const b"%i\n\x00"; + n[60]: copy n[0] => _9 @ bb2[11]: fn inter_function_analysis; _9 = const b"%i\n\x00"; n[61]: copy n[60] => _8 @ bb2[12]: fn inter_function_analysis; _8 = &raw const (*_9); n[62]: copy n[61] => _7 @ bb2[13]: fn inter_function_analysis; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); n[63]: copy n[62] => _6 @ bb2[15]: fn inter_function_analysis; _6 = move _7 as *const i8 (Misc); n[64]: copy n[63] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); - n[65]: copy _ => _11 @ bb2[18]: fn invalid; _11 = const b"%i\n\x00"; + n[65]: copy n[0] => _11 @ bb2[18]: fn invalid; _11 = const b"%i\n\x00"; n[66]: copy n[65] => _10 @ bb2[19]: fn invalid; _10 = &raw const (*_11); n[67]: copy n[66] => _9 @ bb2[20]: fn invalid; _9 = move _10 as *const u8 (Pointer(ArrayToPointer)); n[68]: copy n[67] => _8 @ bb2[22]: fn invalid; _8 = move _9 as *const i8 (Misc); n[69]: copy n[68] => _1 @ bb0[0]: fn printf; _7 = printf(move _8, move _12); - n[70]: copy _ => _17 @ bb3[9]: fn invalid; _17 = const b"%i\n\x00"; + n[70]: copy n[0] => _17 @ bb3[9]: fn invalid; _17 = const b"%i\n\x00"; n[71]: copy n[70] => _16 @ bb3[10]: fn invalid; _16 = &raw const (*_17); n[72]: copy n[71] => _15 @ bb3[11]: fn invalid; _15 = move _16 as *const u8 (Pointer(ArrayToPointer)); n[73]: copy n[72] => _14 @ bb3[13]: fn invalid; _14 = move _15 as *const i8 (Misc); @@ -194,152 +189,152 @@ g { nodes_that_need_write = [] g { - n[0]: alloc _ => _11 @ bb5[2]: fn exercise_allocator; _11 = realloc(move _12, move _14); - n[1]: copy n[0] => _1 @ bb6[2]: fn exercise_allocator; _1 = move _11 as *mut pointers::S (Misc); - n[2]: copy n[1] => _19 @ bb6[6]: fn exercise_allocator; _19 = _1; - n[3]: offset[0] n[2] => _18 @ bb6[7]: fn exercise_allocator; _18 = offset(move _19, const 0_isize); - n[4]: field.0 n[3] => _ @ bb7[1]: fn exercise_allocator; ((*_18).0: i32) = const 10_i32; - n[5]: addr.store n[4] => _ @ bb7[1]: fn exercise_allocator; ((*_18).0: i32) = const 10_i32; - n[6]: copy n[1] => _21 @ bb7[5]: fn exercise_allocator; _21 = _1; - n[7]: offset[1] n[6] => _20 @ bb7[6]: fn exercise_allocator; _20 = offset(move _21, const 1_isize); - n[8]: field.0 n[7] => _ @ bb8[1]: fn exercise_allocator; ((*_20).0: i32) = const 11_i32; - n[9]: addr.store n[8] => _ @ bb8[1]: fn exercise_allocator; ((*_20).0: i32) = const 11_i32; - n[10]: copy n[1] => _34 @ bb11[14]: fn exercise_allocator; _34 = _1; - n[11]: offset[0] n[10] => _33 @ bb11[20]: fn exercise_allocator; _33 = offset(move _34, move _35); - n[12]: field.0 n[11] => _32 @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); - n[13]: addr.load n[12] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); - n[14]: copy n[1] => _34 @ bb11[14]: fn exercise_allocator; _34 = _1; - n[15]: offset[1] n[14] => _33 @ bb11[20]: fn exercise_allocator; _33 = offset(move _34, move _35); - n[16]: field.0 n[15] => _32 @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); - n[17]: addr.load n[16] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); - n[18]: copy n[1] => _43 @ bb21[6]: fn exercise_allocator; _43 = _1; - n[19]: copy n[18] => _42 @ bb21[7]: fn exercise_allocator; _42 = move _43 as *mut libc::c_void (Misc); - n[20]: copy n[1] => _4 @ bb0[1]: fn reallocarray; _4 = _1; - n[21]: copy n[20] => _1 @ bb1[3]: fn reallocarray; _0 = const pointers::REALLOC(move _4, move _5); - n[22]: free n[19] => _41 @ bb22[2]: fn exercise_allocator; _41 = reallocarray(move _42, move _44, move _45); -} -nodes_that_need_write = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - -g { - n[0]: alloc _ => _41 @ bb22[2]: fn exercise_allocator; _41 = reallocarray(move _42, move _44, move _45); - n[1]: copy n[0] => _1 @ bb23[3]: fn exercise_allocator; _1 = move _41 as *mut pointers::S (Misc); - n[2]: copy n[1] => _48 @ bb23[7]: fn exercise_allocator; _48 = _1; - n[3]: offset[0] n[2] => _47 @ bb23[8]: fn exercise_allocator; _47 = offset(move _48, const 0_isize); - n[4]: field.0 n[3] => _ @ bb24[1]: fn exercise_allocator; ((*_47).0: i32) = const 10_i32; - n[5]: addr.store n[4] => _ @ bb24[1]: fn exercise_allocator; ((*_47).0: i32) = const 10_i32; - n[6]: copy n[1] => _50 @ bb24[5]: fn exercise_allocator; _50 = _1; - n[7]: offset[1] n[6] => _49 @ bb24[6]: fn exercise_allocator; _49 = offset(move _50, const 1_isize); - n[8]: field.0 n[7] => _ @ bb25[1]: fn exercise_allocator; ((*_49).0: i32) = const 11_i32; - n[9]: addr.store n[8] => _ @ bb25[1]: fn exercise_allocator; ((*_49).0: i32) = const 11_i32; - n[10]: copy n[1] => _52 @ bb25[5]: fn exercise_allocator; _52 = _1; - n[11]: offset[2] n[10] => _51 @ bb25[6]: fn exercise_allocator; _51 = offset(move _52, const 2_isize); - n[12]: field.0 n[11] => _ @ bb26[1]: fn exercise_allocator; ((*_51).0: i32) = const 12_i32; - n[13]: addr.store n[12] => _ @ bb26[1]: fn exercise_allocator; ((*_51).0: i32) = const 12_i32; - n[14]: copy n[1] => _64 @ bb29[14]: fn exercise_allocator; _64 = _1; - n[15]: offset[0] n[14] => _63 @ bb29[20]: fn exercise_allocator; _63 = offset(move _64, move _65); - n[16]: field.0 n[15] => _62 @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); - n[17]: addr.load n[16] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); - n[18]: copy n[1] => _64 @ bb29[14]: fn exercise_allocator; _64 = _1; - n[19]: offset[1] n[18] => _63 @ bb29[20]: fn exercise_allocator; _63 = offset(move _64, move _65); - n[20]: field.0 n[19] => _62 @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); - n[21]: addr.load n[20] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); - n[22]: copy n[1] => _64 @ bb29[14]: fn exercise_allocator; _64 = _1; - n[23]: offset[2] n[22] => _63 @ bb29[20]: fn exercise_allocator; _63 = offset(move _64, move _65); - n[24]: field.0 n[23] => _62 @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); - n[25]: addr.load n[24] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); - n[26]: copy n[1] => _73 @ bb39[6]: fn exercise_allocator; _73 = _1; - n[27]: copy n[26] => _72 @ bb39[7]: fn exercise_allocator; _72 = move _73 as *mut libc::c_void (Misc); - n[28]: free n[27] => _71 @ bb39[9]: fn exercise_allocator; _71 = free(move _72); -} -nodes_that_need_write = [13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - -g { - n[0]: alloc _ => _74 @ bb41[2]: fn exercise_allocator; _74 = calloc(move _75, move _76); - n[1]: copy n[0] => _1 @ bb42[2]: fn exercise_allocator; _1 = move _74 as *mut pointers::S (Misc); - n[2]: copy n[1] => _79 @ bb42[6]: fn exercise_allocator; _79 = _1; - n[3]: offset[0] n[2] => _78 @ bb42[7]: fn exercise_allocator; _78 = offset(move _79, const 0_isize); - n[4]: field.0 n[3] => _ @ bb43[1]: fn exercise_allocator; ((*_78).0: i32) = const 10_i32; - n[5]: addr.store n[4] => _ @ bb43[1]: fn exercise_allocator; ((*_78).0: i32) = const 10_i32; - n[6]: copy n[1] => _81 @ bb43[5]: fn exercise_allocator; _81 = _1; - n[7]: offset[1] n[6] => _80 @ bb43[6]: fn exercise_allocator; _80 = offset(move _81, const 1_isize); - n[8]: field.0 n[7] => _ @ bb44[1]: fn exercise_allocator; ((*_80).0: i32) = const 11_i32; - n[9]: addr.store n[8] => _ @ bb44[1]: fn exercise_allocator; ((*_80).0: i32) = const 11_i32; - n[10]: copy n[1] => _83 @ bb44[5]: fn exercise_allocator; _83 = _1; - n[11]: offset[2] n[10] => _82 @ bb44[6]: fn exercise_allocator; _82 = offset(move _83, const 2_isize); - n[12]: field.0 n[11] => _ @ bb45[1]: fn exercise_allocator; ((*_82).0: i32) = const 12_i32; - n[13]: addr.store n[12] => _ @ bb45[1]: fn exercise_allocator; ((*_82).0: i32) = const 12_i32; - n[14]: copy n[1] => _85 @ bb45[5]: fn exercise_allocator; _85 = _1; - n[15]: offset[3] n[14] => _84 @ bb45[6]: fn exercise_allocator; _84 = offset(move _85, const 3_isize); - n[16]: field.0 n[15] => _ @ bb46[1]: fn exercise_allocator; ((*_84).0: i32) = const 13_i32; - n[17]: addr.store n[16] => _ @ bb46[1]: fn exercise_allocator; ((*_84).0: i32) = const 13_i32; - n[18]: copy n[1] => _97 @ bb49[14]: fn exercise_allocator; _97 = _1; - n[19]: offset[0] n[18] => _96 @ bb49[20]: fn exercise_allocator; _96 = offset(move _97, move _98); - n[20]: field.0 n[19] => _95 @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); - n[21]: addr.load n[20] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); - n[22]: copy n[1] => _97 @ bb49[14]: fn exercise_allocator; _97 = _1; - n[23]: offset[1] n[22] => _96 @ bb49[20]: fn exercise_allocator; _96 = offset(move _97, move _98); - n[24]: field.0 n[23] => _95 @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); - n[25]: addr.load n[24] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); - n[26]: copy n[1] => _97 @ bb49[14]: fn exercise_allocator; _97 = _1; - n[27]: offset[2] n[26] => _96 @ bb49[20]: fn exercise_allocator; _96 = offset(move _97, move _98); - n[28]: field.0 n[27] => _95 @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); - n[29]: addr.load n[28] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); - n[30]: copy n[1] => _97 @ bb49[14]: fn exercise_allocator; _97 = _1; - n[31]: offset[3] n[30] => _96 @ bb49[20]: fn exercise_allocator; _96 = offset(move _97, move _98); - n[32]: field.0 n[31] => _95 @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); - n[33]: addr.load n[32] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); - n[34]: copy n[1] => _106 @ bb59[6]: fn exercise_allocator; _106 = _1; - n[35]: copy n[34] => _105 @ bb59[7]: fn exercise_allocator; _105 = move _106 as *mut libc::c_void (Misc); - n[36]: free n[35] => _104 @ bb59[9]: fn exercise_allocator; _104 = free(move _105); -} -nodes_that_need_write = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - -g { - n[0]: alloc _ => _2 @ bb1[2]: fn simple_analysis; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn simple_analysis; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[5]: fn simple_analysis; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[5]: fn simple_analysis; ((*_1).0: i32) = const 10_i32; - n[4]: field.0 n[1] => _10 @ bb2[18]: fn simple_analysis; _10 = ((*_1).0: i32); - n[5]: addr.load n[4] => _ @ bb2[18]: fn simple_analysis; _10 = ((*_1).0: i32); - n[6]: copy n[1] => _13 @ bb3[7]: fn simple_analysis; _13 = _1; - n[7]: copy n[6] => _12 @ bb3[8]: fn simple_analysis; _12 = move _13 as *mut libc::c_void (Misc); - n[8]: free n[7] => _11 @ bb3[10]: fn simple_analysis; _11 = free(move _12); + n[0]: alloc _ => _11 @ bb5[2]: fn exercise_allocator; _11 = realloc(move _12, move _14); + n[1]: copy n[0] => _1 @ bb6[2]: fn exercise_allocator; _1 = move _11 as *mut pointers::S (Misc); + n[2]: copy n[1] => _19 @ bb6[6]: fn exercise_allocator; _19 = _1; + n[3]: offset[0] n[2] => _18 @ bb6[7]: fn exercise_allocator; _18 = offset(move _19, const 0_isize); + n[4]: project.0@0 n[3] => _ @ bb7[1]: fn exercise_allocator; ((*_18).0: i32) = const 10_i32; + n[5]: addr.store n[3] => _ @ bb7[1]: fn exercise_allocator; ((*_18).0: i32) = const 10_i32; + n[6]: copy n[1] => _21 @ bb7[5]: fn exercise_allocator; _21 = _1; + n[7]: offset[1] n[6] => _20 @ bb7[6]: fn exercise_allocator; _20 = offset(move _21, const 1_isize); + n[8]: project.0@0 n[7] => _ @ bb8[1]: fn exercise_allocator; ((*_20).0: i32) = const 11_i32; + n[9]: addr.store n[7] => _ @ bb8[1]: fn exercise_allocator; ((*_20).0: i32) = const 11_i32; + n[10]: copy n[1] => _34 @ bb11[14]: fn exercise_allocator; _34 = _1; + n[11]: offset[0] n[10] => _33 @ bb11[20]: fn exercise_allocator; _33 = offset(move _34, move _35); + n[12]: project.0@0 n[11] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); + n[13]: addr.load n[11] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); + n[14]: copy n[1] => _34 @ bb11[14]: fn exercise_allocator; _34 = _1; + n[15]: offset[1] n[14] => _33 @ bb11[20]: fn exercise_allocator; _33 = offset(move _34, move _35); + n[16]: project.0@0 n[15] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); + n[17]: addr.load n[15] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); + n[18]: copy n[1] => _43 @ bb21[6]: fn exercise_allocator; _43 = _1; + n[19]: copy n[18] => _42 @ bb21[7]: fn exercise_allocator; _42 = move _43 as *mut libc::c_void (Misc); + n[20]: copy n[1] => _4 @ bb0[1]: fn reallocarray; _4 = _1; + n[21]: copy n[20] => _1 @ bb1[3]: fn reallocarray; _0 = const pointers::REALLOC(move _4, move _5); + n[22]: free n[19] => _41 @ bb22[2]: fn exercise_allocator; _41 = reallocarray(move _42, move _44, move _45); +} +nodes_that_need_write = [9, 7, 6, 5, 3, 2, 1, 0] + +g { + n[0]: alloc _ => _41 @ bb22[2]: fn exercise_allocator; _41 = reallocarray(move _42, move _44, move _45); + n[1]: copy n[0] => _1 @ bb23[3]: fn exercise_allocator; _1 = move _41 as *mut pointers::S (Misc); + n[2]: copy n[1] => _48 @ bb23[7]: fn exercise_allocator; _48 = _1; + n[3]: offset[0] n[2] => _47 @ bb23[8]: fn exercise_allocator; _47 = offset(move _48, const 0_isize); + n[4]: project.0@0 n[3] => _ @ bb24[1]: fn exercise_allocator; ((*_47).0: i32) = const 10_i32; + n[5]: addr.store n[3] => _ @ bb24[1]: fn exercise_allocator; ((*_47).0: i32) = const 10_i32; + n[6]: copy n[1] => _50 @ bb24[5]: fn exercise_allocator; _50 = _1; + n[7]: offset[1] n[6] => _49 @ bb24[6]: fn exercise_allocator; _49 = offset(move _50, const 1_isize); + n[8]: project.0@0 n[7] => _ @ bb25[1]: fn exercise_allocator; ((*_49).0: i32) = const 11_i32; + n[9]: addr.store n[7] => _ @ bb25[1]: fn exercise_allocator; ((*_49).0: i32) = const 11_i32; + n[10]: copy n[1] => _52 @ bb25[5]: fn exercise_allocator; _52 = _1; + n[11]: offset[2] n[10] => _51 @ bb25[6]: fn exercise_allocator; _51 = offset(move _52, const 2_isize); + n[12]: project.0@0 n[11] => _ @ bb26[1]: fn exercise_allocator; ((*_51).0: i32) = const 12_i32; + n[13]: addr.store n[11] => _ @ bb26[1]: fn exercise_allocator; ((*_51).0: i32) = const 12_i32; + n[14]: copy n[1] => _64 @ bb29[14]: fn exercise_allocator; _64 = _1; + n[15]: offset[0] n[14] => _63 @ bb29[20]: fn exercise_allocator; _63 = offset(move _64, move _65); + n[16]: project.0@0 n[15] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); + n[17]: addr.load n[15] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); + n[18]: copy n[1] => _64 @ bb29[14]: fn exercise_allocator; _64 = _1; + n[19]: offset[1] n[18] => _63 @ bb29[20]: fn exercise_allocator; _63 = offset(move _64, move _65); + n[20]: project.0@0 n[19] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); + n[21]: addr.load n[19] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); + n[22]: copy n[1] => _64 @ bb29[14]: fn exercise_allocator; _64 = _1; + n[23]: offset[2] n[22] => _63 @ bb29[20]: fn exercise_allocator; _63 = offset(move _64, move _65); + n[24]: project.0@0 n[23] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); + n[25]: addr.load n[23] => _ @ bb31[2]: fn exercise_allocator; _62 = ((*_63).0: i32); + n[26]: copy n[1] => _73 @ bb39[6]: fn exercise_allocator; _73 = _1; + n[27]: copy n[26] => _72 @ bb39[7]: fn exercise_allocator; _72 = move _73 as *mut libc::c_void (Misc); + n[28]: free n[27] => _71 @ bb39[9]: fn exercise_allocator; _71 = free(move _72); +} +nodes_that_need_write = [13, 11, 10, 9, 7, 6, 5, 3, 2, 1, 0] + +g { + n[0]: alloc _ => _74 @ bb41[2]: fn exercise_allocator; _74 = calloc(move _75, move _76); + n[1]: copy n[0] => _1 @ bb42[2]: fn exercise_allocator; _1 = move _74 as *mut pointers::S (Misc); + n[2]: copy n[1] => _79 @ bb42[6]: fn exercise_allocator; _79 = _1; + n[3]: offset[0] n[2] => _78 @ bb42[7]: fn exercise_allocator; _78 = offset(move _79, const 0_isize); + n[4]: project.0@0 n[3] => _ @ bb43[1]: fn exercise_allocator; ((*_78).0: i32) = const 10_i32; + n[5]: addr.store n[3] => _ @ bb43[1]: fn exercise_allocator; ((*_78).0: i32) = const 10_i32; + n[6]: copy n[1] => _81 @ bb43[5]: fn exercise_allocator; _81 = _1; + n[7]: offset[1] n[6] => _80 @ bb43[6]: fn exercise_allocator; _80 = offset(move _81, const 1_isize); + n[8]: project.0@0 n[7] => _ @ bb44[1]: fn exercise_allocator; ((*_80).0: i32) = const 11_i32; + n[9]: addr.store n[7] => _ @ bb44[1]: fn exercise_allocator; ((*_80).0: i32) = const 11_i32; + n[10]: copy n[1] => _83 @ bb44[5]: fn exercise_allocator; _83 = _1; + n[11]: offset[2] n[10] => _82 @ bb44[6]: fn exercise_allocator; _82 = offset(move _83, const 2_isize); + n[12]: project.0@0 n[11] => _ @ bb45[1]: fn exercise_allocator; ((*_82).0: i32) = const 12_i32; + n[13]: addr.store n[11] => _ @ bb45[1]: fn exercise_allocator; ((*_82).0: i32) = const 12_i32; + n[14]: copy n[1] => _85 @ bb45[5]: fn exercise_allocator; _85 = _1; + n[15]: offset[3] n[14] => _84 @ bb45[6]: fn exercise_allocator; _84 = offset(move _85, const 3_isize); + n[16]: project.0@0 n[15] => _ @ bb46[1]: fn exercise_allocator; ((*_84).0: i32) = const 13_i32; + n[17]: addr.store n[15] => _ @ bb46[1]: fn exercise_allocator; ((*_84).0: i32) = const 13_i32; + n[18]: copy n[1] => _97 @ bb49[14]: fn exercise_allocator; _97 = _1; + n[19]: offset[0] n[18] => _96 @ bb49[20]: fn exercise_allocator; _96 = offset(move _97, move _98); + n[20]: project.0@0 n[19] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); + n[21]: addr.load n[19] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); + n[22]: copy n[1] => _97 @ bb49[14]: fn exercise_allocator; _97 = _1; + n[23]: offset[1] n[22] => _96 @ bb49[20]: fn exercise_allocator; _96 = offset(move _97, move _98); + n[24]: project.0@0 n[23] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); + n[25]: addr.load n[23] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); + n[26]: copy n[1] => _97 @ bb49[14]: fn exercise_allocator; _97 = _1; + n[27]: offset[2] n[26] => _96 @ bb49[20]: fn exercise_allocator; _96 = offset(move _97, move _98); + n[28]: project.0@0 n[27] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); + n[29]: addr.load n[27] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); + n[30]: copy n[1] => _97 @ bb49[14]: fn exercise_allocator; _97 = _1; + n[31]: offset[3] n[30] => _96 @ bb49[20]: fn exercise_allocator; _96 = offset(move _97, move _98); + n[32]: project.0@0 n[31] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); + n[33]: addr.load n[31] => _ @ bb51[2]: fn exercise_allocator; _95 = ((*_96).0: i32); + n[34]: copy n[1] => _106 @ bb59[6]: fn exercise_allocator; _106 = _1; + n[35]: copy n[34] => _105 @ bb59[7]: fn exercise_allocator; _105 = move _106 as *mut libc::c_void (Misc); + n[36]: free n[35] => _104 @ bb59[9]: fn exercise_allocator; _104 = free(move _105); +} +nodes_that_need_write = [17, 15, 14, 13, 11, 10, 9, 7, 6, 5, 3, 2, 1, 0] + +g { + n[0]: alloc _ => _2 @ bb1[2]: fn simple_analysis; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn simple_analysis; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[5]: fn simple_analysis; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[5]: fn simple_analysis; ((*_1).0: i32) = const 10_i32; + n[4]: project.0@0 n[1] => _ @ bb2[18]: fn simple_analysis; _10 = ((*_1).0: i32); + n[5]: addr.load n[1] => _ @ bb2[18]: fn simple_analysis; _10 = ((*_1).0: i32); + n[6]: copy n[1] => _13 @ bb3[7]: fn simple_analysis; _13 = _1; + n[7]: copy n[6] => _12 @ bb3[8]: fn simple_analysis; _12 = move _13 as *mut libc::c_void (Misc); + n[8]: free n[7] => _11 @ bb3[10]: fn simple_analysis; _11 = free(move _12); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn analysis2; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn analysis2; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[5]: fn analysis2; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[5]: fn analysis2; ((*_1).0: i32) = const 10_i32; - n[4]: copy n[1] => _6 @ bb2[8]: fn analysis2; _6 = _1; - n[5]: copy n[4] => _1 @ bb0[0]: fn analysis2_helper; _5 = analysis2_helper(move _6); - n[6]: field.0 n[5] => _7 @ bb0[12]: fn analysis2_helper; _7 = ((*_1).0: i32); - n[7]: addr.load n[6] => _ @ bb0[12]: fn analysis2_helper; _7 = ((*_1).0: i32); - n[8]: copy n[5] => _9 @ bb3[5]: fn analysis2; _9 = _1; - n[9]: copy n[8] => _8 @ bb3[6]: fn analysis2; _8 = move _9 as *mut libc::c_void (Misc); - n[10]: free n[9] => _7 @ bb3[8]: fn analysis2; _7 = free(move _8); + n[0]: alloc _ => _2 @ bb1[2]: fn analysis2; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn analysis2; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[5]: fn analysis2; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[5]: fn analysis2; ((*_1).0: i32) = const 10_i32; + n[4]: copy n[1] => _6 @ bb2[8]: fn analysis2; _6 = _1; + n[5]: copy n[4] => _1 @ bb0[0]: fn analysis2_helper; _5 = analysis2_helper(move _6); + n[6]: project.0@0 n[5] => _ @ bb0[12]: fn analysis2_helper; _7 = ((*_1).0: i32); + n[7]: addr.load n[5] => _ @ bb0[12]: fn analysis2_helper; _7 = ((*_1).0: i32); + n[8]: copy n[5] => _9 @ bb3[5]: fn analysis2; _9 = _1; + n[9]: copy n[8] => _8 @ bb3[6]: fn analysis2; _8 = move _9 as *mut libc::c_void (Misc); + n[10]: free n[9] => _7 @ bb3[8]: fn analysis2; _7 = free(move _8); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _0 @ bb0[2]: fn malloc_wrapper; _0 = malloc(move _3); - n[1]: copy n[0] => _2 @ bb1[2]: fn inter_function_analysis; _2 = malloc_wrapper(move _3); - n[2]: copy n[1] => _1 @ bb2[1]: fn inter_function_analysis; _1 = move _2 as *mut pointers::S (Misc); - n[3]: field.0 n[2] => _ @ bb2[5]: fn inter_function_analysis; ((*_1).0: i32) = const 11_i32; - n[4]: addr.store n[3] => _ @ bb2[5]: fn inter_function_analysis; ((*_1).0: i32) = const 11_i32; - n[5]: field.0 n[2] => _10 @ bb2[18]: fn inter_function_analysis; _10 = ((*_1).0: i32); - n[6]: addr.load n[5] => _ @ bb2[18]: fn inter_function_analysis; _10 = ((*_1).0: i32); - n[7]: copy n[2] => _13 @ bb3[7]: fn inter_function_analysis; _13 = _1; - n[8]: copy n[7] => _12 @ bb3[8]: fn inter_function_analysis; _12 = move _13 as *mut libc::c_void (Misc); - n[9]: free n[8] => _11 @ bb3[10]: fn inter_function_analysis; _11 = free(move _12); + n[0]: alloc _ => _0 @ bb0[2]: fn malloc_wrapper; _0 = malloc(move _3); + n[1]: copy n[0] => _2 @ bb1[2]: fn inter_function_analysis; _2 = malloc_wrapper(move _3); + n[2]: copy n[1] => _1 @ bb2[1]: fn inter_function_analysis; _1 = move _2 as *mut pointers::S (Misc); + n[3]: project.0@0 n[2] => _ @ bb2[5]: fn inter_function_analysis; ((*_1).0: i32) = const 11_i32; + n[4]: addr.store n[2] => _ @ bb2[5]: fn inter_function_analysis; ((*_1).0: i32) = const 11_i32; + n[5]: project.0@0 n[2] => _ @ bb2[18]: fn inter_function_analysis; _10 = ((*_1).0: i32); + n[6]: addr.load n[2] => _ @ bb2[18]: fn inter_function_analysis; _10 = ((*_1).0: i32); + n[7]: copy n[2] => _13 @ bb3[7]: fn inter_function_analysis; _13 = _1; + n[8]: copy n[7] => _12 @ bb3[8]: fn inter_function_analysis; _12 = move _13 as *mut libc::c_void (Misc); + n[9]: free n[8] => _11 @ bb3[10]: fn inter_function_analysis; _11 = free(move _12); } -nodes_that_need_write = [4, 3, 2, 1, 0] +nodes_that_need_write = [4, 2, 1, 0] g { n[0]: alloc _ => _2 @ bb1[2]: fn no_owner; _2 = malloc(move _3); n[1]: value.store n[0] => _5.* @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); - n[2]: value.load _ => _12 @ bb6[6]: fn main_0; _12 = (*_13); + n[2]: value.load n[0] => _12 @ bb6[6]: fn main_0; _12 = (*_13); n[3]: copy n[2] => _11 @ bb6[7]: fn main_0; _11 = move _12 as *mut libc::c_void (Misc); n[4]: free n[3] => _10 @ bb6[9]: fn main_0; _10 = free(move _11); } @@ -348,45 +343,47 @@ nodes_that_need_write = [] g { n[0]: copy _ => _5 @ bb2[2]: fn no_owner; _5 = const {alloc8: *mut *mut pointers::S}; n[1]: addr.store n[0] => _ @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); - n[2]: copy _ => _13 @ bb6[5]: fn main_0; _13 = const {alloc8: *mut *mut pointers::S}; + n[2]: copy n[0] => _13 @ bb6[5]: fn main_0; _13 = const {alloc8: *mut *mut pointers::S}; n[3]: addr.load n[2] => _ @ bb6[6]: fn main_0; _12 = (*_13); - n[4]: copy _ => _5 @ bb2[2]: fn no_owner; _5 = const {alloc8: *mut *mut pointers::S}; + n[4]: copy n[0] => _5 @ bb2[2]: fn no_owner; _5 = const {alloc8: *mut *mut pointers::S}; n[5]: addr.store n[4] => _ @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); - n[6]: copy _ => _12 @ bb3[4]: fn no_owner; _12 = const {alloc8: *mut *mut pointers::S}; + n[6]: copy n[0] => _12 @ bb3[4]: fn no_owner; _12 = const {alloc8: *mut *mut pointers::S}; n[7]: addr.load n[6] => _ @ bb3[5]: fn no_owner; _11 = (*_12); - n[8]: copy _ => _6 @ bb2[9]: fn invalid; _6 = const {alloc8: *mut *mut pointers::S}; + n[8]: copy n[0] => _6 @ bb2[9]: fn invalid; _6 = const {alloc8: *mut *mut pointers::S}; n[9]: addr.store n[8] => _ @ bb2[10]: fn invalid; (*_6) = move _5; - n[10]: copy _ => _19 @ bb3[17]: fn invalid; _19 = const {alloc8: *mut *mut pointers::S}; - n[11]: field.0 n[10] => _18 @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); - n[12]: addr.load n[11] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); - n[13]: copy _ => _20 @ bb4[6]: fn invalid; _20 = const {alloc8: *mut *mut pointers::S}; - n[14]: addr.store n[13] => _ @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); + n[10]: copy n[0] => _19 @ bb3[17]: fn invalid; _19 = const {alloc8: *mut *mut pointers::S}; + n[11]: addr.load n[10] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[12]: copy n[0] => _20 @ bb4[6]: fn invalid; _20 = const {alloc8: *mut *mut pointers::S}; + n[13]: addr.store n[12] => _ @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); } -nodes_that_need_write = [14, 13, 9, 8, 5, 4, 1, 0] +nodes_that_need_write = [13, 12, 9, 8, 5, 4, 1, 0] g { n[0]: alloc _ => _2 @ bb1[2]: fn no_owner; _2 = malloc(move _3); n[1]: value.store n[0] => _5.* @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); - n[2]: value.load _ => _11 @ bb3[5]: fn no_owner; _11 = (*_12); + n[2]: value.load n[0] => _11 @ bb3[5]: fn no_owner; _11 = (*_12); n[3]: copy n[2] => _10 @ bb3[6]: fn no_owner; _10 = move _11 as *mut libc::c_void (Misc); n[4]: free n[3] => _9 @ bb3[8]: fn no_owner; _9 = free(move _10); } nodes_that_need_write = [] g { - n[0]: alloc _ => _2 @ bb1[2]: fn invalid; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn invalid; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[5]: fn invalid; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[5]: fn invalid; ((*_1).0: i32) = const 10_i32; - n[4]: copy n[1] => _5 @ bb2[7]: fn invalid; _5 = _1; - n[5]: value.store n[4] => _6.* @ bb2[10]: fn invalid; (*_6) = move _5; - n[6]: field.0 n[1] => _12 @ bb2[25]: fn invalid; _12 = ((*_1).0: i32); - n[7]: addr.load n[6] => _ @ bb2[25]: fn invalid; _12 = ((*_1).0: i32); - n[8]: copy n[1] => _23 @ bb4[12]: fn invalid; _23 = _1; - n[9]: copy n[8] => _22 @ bb4[13]: fn invalid; _22 = move _23 as *mut libc::c_void (Misc); - n[10]: free n[9] => _21 @ bb4[15]: fn invalid; _21 = free(move _22); + n[0]: alloc _ => _2 @ bb1[2]: fn invalid; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn invalid; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[5]: fn invalid; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[5]: fn invalid; ((*_1).0: i32) = const 10_i32; + n[4]: copy n[1] => _5 @ bb2[7]: fn invalid; _5 = _1; + n[5]: value.store n[4] => _6.* @ bb2[10]: fn invalid; (*_6) = move _5; + n[6]: project.0@0 n[1] => _ @ bb2[25]: fn invalid; _12 = ((*_1).0: i32); + n[7]: addr.load n[1] => _ @ bb2[25]: fn invalid; _12 = ((*_1).0: i32); + n[8]: value.load n[6] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[9]: project.0@0 n[6] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[10]: addr.load n[9] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[11]: copy n[1] => _23 @ bb4[12]: fn invalid; _23 = _1; + n[12]: copy n[11] => _22 @ bb4[13]: fn invalid; _22 = move _23 as *mut libc::c_void (Misc); + n[13]: free n[12] => _21 @ bb4[15]: fn invalid; _21 = free(move _22); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { n[0]: &_1 _ => _ @ bb0[2]: fn testing; _8 = &raw mut _1; @@ -408,30 +405,30 @@ g { nodes_that_need_write = [3, 2, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn simple1; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn simple1; _1 = move _2 as *mut pointers::S (Misc); - n[2]: copy n[1] => _8 @ bb2[8]: fn simple1; _8 = _1; - n[3]: copy n[2] => _7 @ bb2[9]: fn simple1; _7 = move _8 as *mut libc::c_void (Misc); - n[4]: free n[3] => _6 @ bb3[2]: fn simple1; _6 = realloc(move _7, move _9); - n[5]: copy n[1] => _16 @ bb4[21]: fn simple1; _16 = _1; - n[6]: ptr_to_int n[5] => _ @ bb4[22]: fn simple1; _15 = move _16 as usize (PointerExposeAddress); + n[0]: alloc _ => _2 @ bb1[2]: fn simple1; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn simple1; _1 = move _2 as *mut pointers::S (Misc); + n[2]: copy n[1] => _8 @ bb2[8]: fn simple1; _8 = _1; + n[3]: copy n[2] => _7 @ bb2[9]: fn simple1; _7 = move _8 as *mut libc::c_void (Misc); + n[4]: free n[3] => _6 @ bb3[2]: fn simple1; _6 = realloc(move _7, move _9); } nodes_that_need_write = [] g { - n[0]: alloc _ => _6 @ bb3[2]: fn simple1; _6 = realloc(move _7, move _9); - n[1]: copy n[0] => _5 @ bb4[2]: fn simple1; _5 = move _6 as *mut pointers::S (Misc); - n[2]: copy n[1] => _11 @ bb4[6]: fn simple1; _11 = _5; - n[3]: field.0 n[2] => _ @ bb4[8]: fn simple1; ((*_11).0: i32) = const 10_i32; - n[4]: addr.store n[3] => _ @ bb4[8]: fn simple1; ((*_11).0: i32) = const 10_i32; - n[5]: copy n[1] => _12 @ bb4[10]: fn simple1; _12 = _5; - n[6]: copy n[2] => _13 @ bb4[13]: fn simple1; _13 = _11; - n[7]: int_to_ptr _ => _17 @ bb4[28]: fn simple1; _17 = move _18 as *const libc::c_void (PointerFromExposedAddress); - n[8]: copy n[1] => _21 @ bb4[34]: fn simple1; _21 = _5; - n[9]: copy n[8] => _20 @ bb4[35]: fn simple1; _20 = move _21 as *mut libc::c_void (Misc); - n[10]: free n[9] => _19 @ bb4[37]: fn simple1; _19 = free(move _20); + n[0]: alloc _ => _6 @ bb3[2]: fn simple1; _6 = realloc(move _7, move _9); + n[1]: copy n[0] => _5 @ bb4[2]: fn simple1; _5 = move _6 as *mut pointers::S (Misc); + n[2]: copy n[1] => _11 @ bb4[6]: fn simple1; _11 = _5; + n[3]: project.0@0 n[2] => _ @ bb4[8]: fn simple1; ((*_11).0: i32) = const 10_i32; + n[4]: addr.store n[2] => _ @ bb4[8]: fn simple1; ((*_11).0: i32) = const 10_i32; + n[5]: copy n[1] => _12 @ bb4[10]: fn simple1; _12 = _5; + n[6]: copy n[2] => _13 @ bb4[13]: fn simple1; _13 = _11; + n[7]: copy n[3] => _16 @ bb4[21]: fn simple1; _16 = _1; + n[8]: ptr_to_int n[7] => _ @ bb4[22]: fn simple1; _15 = move _16 as usize (PointerExposeAddress); + n[9]: int_to_ptr n[3] => _17 @ bb4[28]: fn simple1; _17 = move _18 as *const libc::c_void (PointerFromExposedAddress); + n[10]: copy n[1] => _21 @ bb4[34]: fn simple1; _21 = _5; + n[11]: copy n[10] => _20 @ bb4[35]: fn simple1; _20 = move _21 as *mut libc::c_void (Misc); + n[12]: free n[11] => _19 @ bb4[37]: fn simple1; _19 = free(move _20); } -nodes_that_need_write = [4, 3, 2, 1, 0] +nodes_that_need_write = [4, 2, 1, 0] g { n[0]: &_13 _ => _ @ bb4[14]: fn simple1; _22 = &raw mut _13; @@ -445,15 +442,15 @@ g { n[1]: copy n[0] => _1 @ bb2[1]: fn lighttpd_test; _1 = move _2 as *mut *mut pointers::fdnode_st (Misc); n[2]: copy n[1] => _9 @ bb4[5]: fn lighttpd_test; _9 = _1; n[3]: value.store n[2] => _5.*.0 @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; - n[4]: value.load _ => _8 @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[4]: value.load n[0] => _8 @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); n[5]: offset[0] n[4] => _7 @ bb0[8]: fn fdevent_register; _7 = offset(move _8, move _9); n[6]: copy n[5] => _6 @ bb1[3]: fn fdevent_register; _6 = &mut (*_7); n[7]: addr.store n[6] => _ @ bb2[0]: fn fdevent_register; (*_6) = move _11; n[8]: addr.load n[6] => _ @ bb2[3]: fn fdevent_register; _12 = (*_6); - n[9]: value.load _ => _5 @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[9]: value.load n[5] => _5 @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); n[10]: offset[0] n[9] => _4 @ bb0[9]: fn fdevent_unregister; _4 = offset(move _5, move _6); n[11]: addr.load n[10] => _ @ bb1[2]: fn fdevent_unregister; _3 = (*_4); - n[12]: value.load _ => _19 @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[12]: value.load n[10] => _19 @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); n[13]: offset[0] n[12] => _18 @ bb7[10]: fn fdevent_unregister; _18 = offset(move _19, move _20); n[14]: copy n[13] => _17 @ bb8[3]: fn fdevent_unregister; _17 = &mut (*_18); n[15]: addr.store n[14] => _ @ bb8[4]: fn fdevent_unregister; (*_17) = const 0_usize as *mut pointers::fdnode_st (PointerFromExposedAddress); @@ -461,119 +458,119 @@ g { n[17]: copy n[16] => _19 @ bb6[7]: fn lighttpd_test; _19 = move _20 as *mut libc::c_void (Misc); n[18]: free n[17] => _18 @ bb6[9]: fn lighttpd_test; _18 = free(move _19); } -nodes_that_need_write = [15, 14, 13, 12, 7, 6, 5, 4] - -g { - n[0]: alloc _ => _6 @ bb3[2]: fn lighttpd_test; _6 = malloc(move _7); - n[1]: copy n[0] => _5 @ bb4[1]: fn lighttpd_test; _5 = move _6 as *mut pointers::fdevents (Misc); - n[2]: field.0 n[1] => _ @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; - n[3]: addr.store n[2] => _ @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; - n[4]: copy n[1] => _12 @ bb4[10]: fn lighttpd_test; _12 = _5; - n[5]: value.load _ => _10 @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); - n[6]: copy n[5] => _1 @ bb0[0]: fn fdevent_register; _9 = fdevent_register(move _10, move _11, move _12, move _14); - n[7]: field.0 n[6] => _8 @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[8]: addr.load n[7] => _ @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[9]: value.load _ => _4 @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); - n[10]: copy n[9] => _1 @ bb0[0]: fn fdevent_fdnode_event_del; _3 = fdevent_fdnode_event_del(move _4, move _5); - n[11]: copy n[10] => _7 @ bb2[2]: fn fdevent_fdnode_event_del; _7 = _1; - n[12]: copy n[11] => _1 @ bb0[0]: fn fdevent_fdnode_event_unsetter; _6 = fdevent_fdnode_event_unsetter(move _7, move _8); - n[13]: value.load _ => _7 @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); - n[14]: copy n[13] => _1 @ bb0[0]: fn fdevent_unregister; _6 = fdevent_unregister(move _7, move _8); - n[15]: field.0 n[14] => _5 @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[16]: addr.load n[15] => _ @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[17]: field.0 n[14] => _19 @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[18]: addr.load n[17] => _ @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[19]: copy n[15] => _23 @ bb7[5]: fn lighttpd_test; _23 = _5; - n[20]: copy n[19] => _22 @ bb7[6]: fn lighttpd_test; _22 = move _23 as *mut libc::c_void (Misc); - n[21]: free n[20] => _21 @ bb7[8]: fn lighttpd_test; _21 = free(move _22); +nodes_that_need_write = [15, 14, 13, 12, 10, 9, 7, 6, 5, 4, 0] + +g { + n[0]: alloc _ => _6 @ bb3[2]: fn lighttpd_test; _6 = malloc(move _7); + n[1]: copy n[0] => _5 @ bb4[1]: fn lighttpd_test; _5 = move _6 as *mut pointers::fdevents (Misc); + n[2]: project.0@0 n[1] => _ @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; + n[3]: addr.store n[1] => _ @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; + n[4]: copy n[1] => _12 @ bb4[10]: fn lighttpd_test; _12 = _5; + n[5]: value.load n[2] => _10 @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); + n[6]: copy n[5] => _1 @ bb0[0]: fn fdevent_register; _9 = fdevent_register(move _10, move _11, move _12, move _14); + n[7]: project.0@0 n[6] => _ @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[8]: addr.load n[6] => _ @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[9]: value.load n[7] => _4 @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); + n[10]: copy n[9] => _1 @ bb0[0]: fn fdevent_fdnode_event_del; _3 = fdevent_fdnode_event_del(move _4, move _5); + n[11]: copy n[10] => _7 @ bb2[2]: fn fdevent_fdnode_event_del; _7 = _1; + n[12]: copy n[11] => _1 @ bb0[0]: fn fdevent_fdnode_event_unsetter; _6 = fdevent_fdnode_event_unsetter(move _7, move _8); + n[13]: value.load n[7] => _7 @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); + n[14]: copy n[13] => _1 @ bb0[0]: fn fdevent_unregister; _6 = fdevent_unregister(move _7, move _8); + n[15]: project.0@0 n[14] => _ @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[16]: addr.load n[14] => _ @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[17]: project.0@0 n[14] => _ @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[18]: addr.load n[14] => _ @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[19]: copy n[1] => _23 @ bb7[5]: fn lighttpd_test; _23 = _5; + n[20]: copy n[19] => _22 @ bb7[6]: fn lighttpd_test; _22 = move _23 as *mut libc::c_void (Misc); + n[21]: free n[20] => _21 @ bb7[8]: fn lighttpd_test; _21 = free(move _22); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: &_11 _ => _ @ bb4[12]: fn lighttpd_test; _24 = &raw mut _11; - n[1]: addr.store n[0] => _ @ bb4[11]: fn lighttpd_test; _11 = pointers::server { ev: move _12 }; - n[2]: copy n[0] => _10 @ bb4[15]: fn lighttpd_test; _10 = &mut (*_24); - n[3]: copy n[2] => _14 @ bb4[18]: fn lighttpd_test; _14 = &raw mut (*_10); - n[4]: copy n[3] => _1 @ bb0[0]: fn connection_accepted; _13 = connection_accepted(move _14, const 0_i32); - n[5]: field.0 n[4] => _10 @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); - n[6]: addr.load n[5] => _ @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); - n[7]: copy n[5] => _16 @ bb5[4]: fn lighttpd_test; _16 = &raw mut (*_10); - n[8]: copy n[7] => _1 @ bb0[0]: fn connection_close; _15 = connection_close(move _16, move _17); - n[9]: field.0 n[8] => _4 @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); - n[10]: addr.load n[9] => _ @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); - n[11]: field.0 n[8] => _7 @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); - n[12]: addr.load n[11] => _ @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); + n[0]: &_11 _ => _ @ bb4[12]: fn lighttpd_test; _24 = &raw mut _11; + n[1]: addr.store n[0] => _ @ bb4[11]: fn lighttpd_test; _11 = pointers::server { ev: move _12 }; + n[2]: copy n[0] => _10 @ bb4[15]: fn lighttpd_test; _10 = &mut (*_24); + n[3]: copy n[2] => _14 @ bb4[18]: fn lighttpd_test; _14 = &raw mut (*_10); + n[4]: copy n[3] => _1 @ bb0[0]: fn connection_accepted; _13 = connection_accepted(move _14, const 0_i32); + n[5]: project.0@0 n[4] => _ @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); + n[6]: addr.load n[4] => _ @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); + n[7]: copy n[2] => _16 @ bb5[4]: fn lighttpd_test; _16 = &raw mut (*_10); + n[8]: copy n[7] => _1 @ bb0[0]: fn connection_close; _15 = connection_close(move _16, move _17); + n[9]: project.0@0 n[8] => _ @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); + n[10]: addr.load n[8] => _ @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); + n[11]: project.0@0 n[8] => _ @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); + n[12]: addr.load n[8] => _ @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); } nodes_that_need_write = [1, 0] g { n[0]: alloc _ => _5 @ bb1[2]: fn connection_accepted; _5 = malloc(move _6); n[1]: copy n[0] => _4 @ bb2[1]: fn connection_accepted; _4 = move _5 as *mut pointers::connection (Misc); - n[2]: field.0 n[1] => _ @ bb2[6]: fn connection_accepted; ((*_4).0: i32) = move _8; - n[3]: addr.store n[2] => _ @ bb2[6]: fn connection_accepted; ((*_4).0: i32) = move _8; - n[4]: field.0 n[1] => _11 @ bb2[12]: fn connection_accepted; _11 = ((*_4).0: i32); - n[5]: addr.load n[4] => _ @ bb2[12]: fn connection_accepted; _11 = ((*_4).0: i32); + n[2]: project.0@0 n[1] => _ @ bb2[6]: fn connection_accepted; ((*_4).0: i32) = move _8; + n[3]: addr.store n[1] => _ @ bb2[6]: fn connection_accepted; ((*_4).0: i32) = move _8; + n[4]: project.0@0 n[1] => _ @ bb2[12]: fn connection_accepted; _11 = ((*_4).0: i32); + n[5]: addr.load n[1] => _ @ bb2[12]: fn connection_accepted; _11 = ((*_4).0: i32); n[6]: copy n[1] => _15 @ bb2[20]: fn connection_accepted; _15 = _4; n[7]: copy n[6] => _14 @ bb2[21]: fn connection_accepted; _14 = move _15 as *mut libc::c_void (Misc); n[8]: copy n[7] => _4 @ bb0[0]: fn fdevent_register; _9 = fdevent_register(move _10, move _11, move _12, move _14); n[9]: copy n[8] => _15 @ bb2[15]: fn fdevent_register; _15 = _4; n[10]: value.store n[9] => _12.*.1 @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; - n[11]: field.1 n[1] => _ @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; - n[12]: addr.store n[11] => _ @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; + n[11]: project.1@8 n[8] => _ @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; + n[12]: addr.store n[8] => _ @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; n[13]: copy n[8] => _0 @ bb3[6]: fn connection_accepted; _0 = _4; n[14]: copy n[13] => _13 @ bb4[19]: fn lighttpd_test; _13 = connection_accepted(move _14, const 0_i32); n[15]: copy n[14] => _17 @ bb5[6]: fn lighttpd_test; _17 = _13; n[16]: copy n[15] => _2 @ bb0[0]: fn connection_close; _15 = connection_close(move _16, move _17); - n[17]: field.1 n[16] => _5 @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); - n[18]: addr.load n[17] => _ @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); - n[19]: field.0 n[16] => _8 @ bb1[7]: fn connection_close; _8 = ((*_2).0: i32); - n[20]: addr.load n[19] => _ @ bb1[7]: fn connection_close; _8 = ((*_2).0: i32); + n[17]: project.1@8 n[16] => _ @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); + n[18]: addr.load n[16] => _ @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); + n[19]: project.0@0 n[16] => _ @ bb1[7]: fn connection_close; _8 = ((*_2).0: i32); + n[20]: addr.load n[16] => _ @ bb1[7]: fn connection_close; _8 = ((*_2).0: i32); n[21]: copy n[16] => _11 @ bb2[6]: fn connection_close; _11 = _2; n[22]: copy n[21] => _10 @ bb2[7]: fn connection_close; _10 = move _11 as *mut libc::c_void (Misc); n[23]: free n[22] => _9 @ bb2[9]: fn connection_close; _9 = free(move _10); } -nodes_that_need_write = [12, 11, 3, 2, 1, 0] - -g { - n[0]: alloc _ => _3 @ bb1[2]: fn fdnode_init; _3 = calloc(move _4, move _6); - n[1]: copy n[0] => _2 @ bb2[2]: fn fdnode_init; _2 = move _3 as *mut pointers::fdnode_st (Misc); - n[2]: copy n[1] => _10 @ bb2[9]: fn fdnode_init; _10 = _2; - n[3]: copy n[2] => _1 @ bb0[0]: fn is_null; _9 = is_null(move _10); - n[4]: copy n[1] => _0 @ bb9[2]: fn fdnode_init; _0 = _2; - n[5]: copy n[4] => _11 @ bb1[5]: fn fdevent_register; _11 = fdnode_init(); - n[6]: value.store n[5] => _6.* @ bb2[0]: fn fdevent_register; (*_6) = move _11; - n[7]: value.load _ => _12 @ bb2[3]: fn fdevent_register; _12 = (*_6); - n[8]: field.0 n[7] => _ @ bb2[8]: fn fdevent_register; ((*_12).0: std::option::Option u32>) = move _13; - n[9]: addr.store n[8] => _ @ bb2[8]: fn fdevent_register; ((*_12).0: std::option::Option u32>) = move _13; - n[10]: field.2 n[7] => _ @ bb2[12]: fn fdevent_register; ((*_12).2: i32) = move _14; - n[11]: addr.store n[10] => _ @ bb2[12]: fn fdevent_register; ((*_12).2: i32) = move _14; - n[12]: field.1 n[7] => _ @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; - n[13]: addr.store n[12] => _ @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; - n[14]: field.3 n[7] => _ @ bb2[20]: fn fdevent_register; ((*_12).3: i32) = move _16; - n[15]: addr.store n[14] => _ @ bb2[20]: fn fdevent_register; ((*_12).3: i32) = move _16; - n[16]: field.4 n[7] => _ @ bb3[0]: fn fdevent_register; ((*_12).4: i32) = Neg(move _17); - n[17]: addr.store n[16] => _ @ bb3[0]: fn fdevent_register; ((*_12).4: i32) = Neg(move _17); - n[18]: copy n[7] => _0 @ bb3[2]: fn fdevent_register; _0 = _12; - n[19]: copy n[18] => _9 @ bb2[23]: fn connection_accepted; _9 = fdevent_register(move _10, move _11, move _12, move _14); - n[20]: value.store n[19] => _4.*.1 @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; - n[21]: value.load _ => _5 @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); - n[22]: copy n[21] => _2 @ bb0[0]: fn fdevent_fdnode_event_del; _3 = fdevent_fdnode_event_del(move _4, move _5); - n[23]: copy n[22] => _5 @ bb0[3]: fn fdevent_fdnode_event_del; _5 = _2; - n[24]: copy n[23] => _1 @ bb0[0]: fn is_null; _4 = is_null(move _5); - n[25]: copy n[22] => _8 @ bb2[4]: fn fdevent_fdnode_event_del; _8 = _2; - n[26]: copy n[25] => _2 @ bb0[0]: fn fdevent_fdnode_event_unsetter; _6 = fdevent_fdnode_event_unsetter(move _7, move _8); - n[27]: field.4 n[26] => _8 @ bb1[3]: fn fdevent_fdnode_event_unsetter; _8 = ((*_2).4: i32); - n[28]: addr.load n[27] => _ @ bb1[3]: fn fdevent_fdnode_event_unsetter; _8 = ((*_2).4: i32); - n[29]: value.load _ => _3 @ bb1[2]: fn fdevent_unregister; _3 = (*_4); - n[30]: copy n[29] => _12 @ bb1[11]: fn fdevent_unregister; _12 = _3; - n[31]: ptr_to_int n[30] => _ @ bb1[12]: fn fdevent_unregister; _11 = move _12 as usize (PointerExposeAddress); - n[32]: copy n[29] => _23 @ bb8[7]: fn fdevent_unregister; _23 = _3; - n[33]: copy n[32] => _1 @ bb0[0]: fn fdnode_free; _22 = fdnode_free(move _23); - n[34]: copy n[33] => _4 @ bb0[3]: fn fdnode_free; _4 = _1; - n[35]: copy n[34] => _3 @ bb0[4]: fn fdnode_free; _3 = move _4 as *mut libc::c_void (Misc); - n[36]: free n[35] => _2 @ bb0[6]: fn fdnode_free; _2 = free(move _3); -} -nodes_that_need_write = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7] +nodes_that_need_write = [12, 8, 7, 6, 3, 1, 0] + +g { + n[0]: alloc _ => _3 @ bb1[2]: fn fdnode_init; _3 = calloc(move _4, move _6); + n[1]: copy n[0] => _2 @ bb2[2]: fn fdnode_init; _2 = move _3 as *mut pointers::fdnode_st (Misc); + n[2]: copy n[1] => _10 @ bb2[9]: fn fdnode_init; _10 = _2; + n[3]: copy n[2] => _1 @ bb0[0]: fn is_null; _9 = is_null(move _10); + n[4]: copy n[1] => _0 @ bb9[2]: fn fdnode_init; _0 = _2; + n[5]: copy n[4] => _11 @ bb1[5]: fn fdevent_register; _11 = fdnode_init(); + n[6]: value.store n[5] => _6.* @ bb2[0]: fn fdevent_register; (*_6) = move _11; + n[7]: value.load n[0] => _12 @ bb2[3]: fn fdevent_register; _12 = (*_6); + n[8]: project.0@0 n[7] => _ @ bb2[8]: fn fdevent_register; ((*_12).0: std::option::Option u32>) = move _13; + n[9]: addr.store n[7] => _ @ bb2[8]: fn fdevent_register; ((*_12).0: std::option::Option u32>) = move _13; + n[10]: project.2@16 n[7] => _ @ bb2[12]: fn fdevent_register; ((*_12).2: i32) = move _14; + n[11]: addr.store n[7] => _ @ bb2[12]: fn fdevent_register; ((*_12).2: i32) = move _14; + n[12]: project.1@8 n[7] => _ @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; + n[13]: addr.store n[7] => _ @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; + n[14]: project.3@20 n[7] => _ @ bb2[20]: fn fdevent_register; ((*_12).3: i32) = move _16; + n[15]: addr.store n[7] => _ @ bb2[20]: fn fdevent_register; ((*_12).3: i32) = move _16; + n[16]: project.4@24 n[7] => _ @ bb3[0]: fn fdevent_register; ((*_12).4: i32) = Neg(move _17); + n[17]: addr.store n[7] => _ @ bb3[0]: fn fdevent_register; ((*_12).4: i32) = Neg(move _17); + n[18]: copy n[7] => _0 @ bb3[2]: fn fdevent_register; _0 = _12; + n[19]: copy n[18] => _9 @ bb2[23]: fn connection_accepted; _9 = fdevent_register(move _10, move _11, move _12, move _14); + n[20]: value.store n[19] => _4.*.1 @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; + n[21]: value.load n[8] => _5 @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); + n[22]: copy n[21] => _2 @ bb0[0]: fn fdevent_fdnode_event_del; _3 = fdevent_fdnode_event_del(move _4, move _5); + n[23]: copy n[22] => _5 @ bb0[3]: fn fdevent_fdnode_event_del; _5 = _2; + n[24]: copy n[23] => _1 @ bb0[0]: fn is_null; _4 = is_null(move _5); + n[25]: copy n[22] => _8 @ bb2[4]: fn fdevent_fdnode_event_del; _8 = _2; + n[26]: copy n[25] => _2 @ bb0[0]: fn fdevent_fdnode_event_unsetter; _6 = fdevent_fdnode_event_unsetter(move _7, move _8); + n[27]: project.4@24 n[26] => _ @ bb1[3]: fn fdevent_fdnode_event_unsetter; _8 = ((*_2).4: i32); + n[28]: addr.load n[26] => _ @ bb1[3]: fn fdevent_fdnode_event_unsetter; _8 = ((*_2).4: i32); + n[29]: value.load n[8] => _3 @ bb1[2]: fn fdevent_unregister; _3 = (*_4); + n[30]: copy n[29] => _12 @ bb1[11]: fn fdevent_unregister; _12 = _3; + n[31]: ptr_to_int n[30] => _ @ bb1[12]: fn fdevent_unregister; _11 = move _12 as usize (PointerExposeAddress); + n[32]: copy n[29] => _23 @ bb8[7]: fn fdevent_unregister; _23 = _3; + n[33]: copy n[32] => _1 @ bb0[0]: fn fdnode_free; _22 = fdnode_free(move _23); + n[34]: copy n[33] => _4 @ bb0[3]: fn fdnode_free; _4 = _1; + n[35]: copy n[34] => _3 @ bb0[4]: fn fdnode_free; _3 = move _4 as *mut libc::c_void (Misc); + n[36]: free n[35] => _2 @ bb0[6]: fn fdnode_free; _2 = free(move _3); +} +nodes_that_need_write = [17, 15, 13, 11, 9, 7, 0] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_malloc_free; _1 = malloc(move _2); @@ -717,73 +714,71 @@ g { nodes_that_need_write = [] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_store_addr; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn test_store_addr; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[4]: fn test_store_addr; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[4]: fn test_store_addr; ((*_1).0: i32) = const 10_i32; - n[4]: copy n[1] => _7 @ bb2[8]: fn test_store_addr; _7 = _1; - n[5]: copy n[4] => _6 @ bb2[9]: fn test_store_addr; _6 = move _7 as *mut libc::c_void (Misc); - n[6]: free n[5] => _5 @ bb2[11]: fn test_store_addr; _5 = free(move _6); + n[0]: alloc _ => _2 @ bb1[2]: fn test_store_addr; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn test_store_addr; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[4]: fn test_store_addr; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[4]: fn test_store_addr; ((*_1).0: i32) = const 10_i32; + n[4]: copy n[1] => _7 @ bb2[8]: fn test_store_addr; _7 = _1; + n[5]: copy n[4] => _6 @ bb2[9]: fn test_store_addr; _6 = move _7 as *mut libc::c_void (Misc); + n[6]: free n[5] => _5 @ bb2[11]: fn test_store_addr; _5 = free(move _6); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_load_other_store_self; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn test_load_other_store_self; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb4[4]: fn test_load_other_store_self; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb4[4]: fn test_load_other_store_self; ((*_1).0: i32) = const 10_i32; - n[4]: field.0 n[1] => _9 @ bb4[6]: fn test_load_other_store_self; _9 = ((*_1).0: i32); - n[5]: addr.load n[4] => _ @ bb4[6]: fn test_load_other_store_self; _9 = ((*_1).0: i32); - n[6]: copy n[1] => _12 @ bb4[12]: fn test_load_other_store_self; _12 = _1; - n[7]: copy n[6] => _11 @ bb4[13]: fn test_load_other_store_self; _11 = move _12 as *mut libc::c_void (Misc); - n[8]: free n[7] => _10 @ bb4[15]: fn test_load_other_store_self; _10 = free(move _11); + n[0]: alloc _ => _2 @ bb1[2]: fn test_load_other_store_self; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn test_load_other_store_self; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb4[4]: fn test_load_other_store_self; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb4[4]: fn test_load_other_store_self; ((*_1).0: i32) = const 10_i32; + n[4]: project.0@0 n[1] => _ @ bb4[6]: fn test_load_other_store_self; _9 = ((*_1).0: i32); + n[5]: addr.load n[1] => _ @ bb4[6]: fn test_load_other_store_self; _9 = ((*_1).0: i32); + n[6]: copy n[1] => _12 @ bb4[12]: fn test_load_other_store_self; _12 = _1; + n[7]: copy n[6] => _11 @ bb4[13]: fn test_load_other_store_self; _11 = move _12 as *mut libc::c_void (Misc); + n[8]: free n[7] => _10 @ bb4[15]: fn test_load_other_store_self; _10 = free(move _11); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _6 @ bb3[2]: fn test_load_other_store_self; _6 = malloc(move _7); - n[1]: copy n[0] => _5 @ bb4[1]: fn test_load_other_store_self; _5 = move _6 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb4[7]: fn test_load_other_store_self; ((*_5).0: i32) = move _9; - n[3]: addr.store n[2] => _ @ bb4[7]: fn test_load_other_store_self; ((*_5).0: i32) = move _9; - n[4]: copy n[1] => _15 @ bb5[5]: fn test_load_other_store_self; _15 = _5; - n[5]: copy n[4] => _14 @ bb5[6]: fn test_load_other_store_self; _14 = move _15 as *mut libc::c_void (Misc); - n[6]: free n[5] => _13 @ bb5[8]: fn test_load_other_store_self; _13 = free(move _14); + n[0]: alloc _ => _6 @ bb3[2]: fn test_load_other_store_self; _6 = malloc(move _7); + n[1]: copy n[0] => _5 @ bb4[1]: fn test_load_other_store_self; _5 = move _6 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb4[7]: fn test_load_other_store_self; ((*_5).0: i32) = move _9; + n[3]: addr.store n[1] => _ @ bb4[7]: fn test_load_other_store_self; ((*_5).0: i32) = move _9; + n[4]: copy n[1] => _15 @ bb5[5]: fn test_load_other_store_self; _15 = _5; + n[5]: copy n[4] => _14 @ bb5[6]: fn test_load_other_store_self; _14 = move _15 as *mut libc::c_void (Misc); + n[6]: free n[5] => _13 @ bb5[8]: fn test_load_other_store_self; _13 = free(move _14); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_load_self_store_self; _2 = calloc(move _3, move _4); - n[1]: copy n[0] => _1 @ bb2[2]: fn test_load_self_store_self; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.3 n[1] => _ @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); - n[3]: field.3 n[2] => _6 @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); - n[4]: addr.load n[3] => _ @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); - n[5]: field.3 n[1] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; - n[6]: field.3 n[5] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; - n[7]: addr.store n[6] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; - n[8]: copy n[1] => _9 @ bb2[12]: fn test_load_self_store_self; _9 = _1; - n[9]: copy n[8] => _8 @ bb2[13]: fn test_load_self_store_self; _8 = move _9 as *mut libc::c_void (Misc); - n[10]: free n[9] => _7 @ bb2[15]: fn test_load_self_store_self; _7 = free(move _8); + n[0]: alloc _ => _2 @ bb1[2]: fn test_load_self_store_self; _2 = calloc(move _3, move _4); + n[1]: copy n[0] => _1 @ bb2[2]: fn test_load_self_store_self; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.5@48 n[1] => _ @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); + n[3]: addr.load n[1] => _ @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); + n[4]: project.5@48 n[1] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; + n[5]: addr.store n[1] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; + n[6]: copy n[1] => _9 @ bb2[12]: fn test_load_self_store_self; _9 = _1; + n[7]: copy n[6] => _8 @ bb2[13]: fn test_load_self_store_self; _8 = move _9 as *mut libc::c_void (Misc); + n[8]: free n[7] => _7 @ bb2[15]: fn test_load_self_store_self; _7 = free(move _8); } -nodes_that_need_write = [7, 6, 5, 1, 0] +nodes_that_need_write = [5, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_load_self_store_self_inter; _2 = calloc(move _3, move _4); - n[1]: copy n[0] => _1 @ bb2[2]: fn test_load_self_store_self_inter; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _6 @ bb2[6]: fn test_load_self_store_self_inter; _6 = ((*_1).0: i32); - n[3]: addr.load n[2] => _ @ bb2[6]: fn test_load_self_store_self_inter; _6 = ((*_1).0: i32); - n[4]: field.0 n[1] => _ @ bb2[10]: fn test_load_self_store_self_inter; ((*_1).0: i32) = move _7; - n[5]: addr.store n[4] => _ @ bb2[10]: fn test_load_self_store_self_inter; ((*_1).0: i32) = move _7; - n[6]: copy n[1] => _10 @ bb2[15]: fn test_load_self_store_self_inter; _10 = _1; - n[7]: copy n[6] => _9 @ bb2[16]: fn test_load_self_store_self_inter; _9 = move _10 as *mut libc::c_void (Misc); - n[8]: free n[7] => _8 @ bb2[18]: fn test_load_self_store_self_inter; _8 = free(move _9); + n[0]: alloc _ => _2 @ bb1[2]: fn test_load_self_store_self_inter; _2 = calloc(move _3, move _4); + n[1]: copy n[0] => _1 @ bb2[2]: fn test_load_self_store_self_inter; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[6]: fn test_load_self_store_self_inter; _6 = ((*_1).0: i32); + n[3]: addr.load n[1] => _ @ bb2[6]: fn test_load_self_store_self_inter; _6 = ((*_1).0: i32); + n[4]: project.0@0 n[1] => _ @ bb2[10]: fn test_load_self_store_self_inter; ((*_1).0: i32) = move _7; + n[5]: addr.store n[1] => _ @ bb2[10]: fn test_load_self_store_self_inter; ((*_1).0: i32) = move _7; + n[6]: copy n[1] => _10 @ bb2[15]: fn test_load_self_store_self_inter; _10 = _1; + n[7]: copy n[6] => _9 @ bb2[16]: fn test_load_self_store_self_inter; _9 = move _10 as *mut libc::c_void (Misc); + n[8]: free n[7] => _8 @ bb2[18]: fn test_load_self_store_self_inter; _8 = free(move _9); } -nodes_that_need_write = [5, 4, 1, 0] +nodes_that_need_write = [5, 1, 0] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_ptr_int_ptr; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_ptr_int_ptr; _5 = _1; n[2]: ptr_to_int n[1] => _ @ bb2[5]: fn test_ptr_int_ptr; _4 = move _5 as usize (PointerExposeAddress); - n[3]: int_to_ptr _ => _1 @ bb2[10]: fn test_ptr_int_ptr; _1 = move _6 as *mut libc::c_void (PointerFromExposedAddress); + n[3]: int_to_ptr n[0] => _1 @ bb2[10]: fn test_ptr_int_ptr; _1 = move _6 as *mut libc::c_void (PointerFromExposedAddress); n[4]: copy n[3] => _8 @ bb2[14]: fn test_ptr_int_ptr; _8 = _1; n[5]: free n[4] => _7 @ bb2[15]: fn test_ptr_int_ptr; _7 = free(move _8); } @@ -791,7 +786,7 @@ nodes_that_need_write = [] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_load_value; _1 = malloc(move _2); - n[1]: value.load _ => _6 @ bb2[8]: fn test_load_value; _6 = (*_4); + n[1]: value.load n[0] => _6 @ bb2[8]: fn test_load_value; _6 = (*_4); n[2]: free n[1] => _5 @ bb2[9]: fn test_load_value; _5 = free(move _6); } nodes_that_need_write = [] @@ -805,10 +800,10 @@ nodes_that_need_write = [] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_store_value; _1 = malloc(move _2); - n[1]: value.load _ => _4 @ bb2[4]: fn test_store_value; _4 = (*_9); + n[1]: value.load n[0] => _4 @ bb2[4]: fn test_store_value; _4 = (*_9); n[2]: copy n[1] => _6 @ bb2[10]: fn test_store_value; _6 = _4; n[3]: value.store n[2] => _5.* @ bb2[11]: fn test_store_value; (*_5) = move _6; - n[4]: value.load _ => _8 @ bb2[15]: fn test_store_value; _8 = (*_9); + n[4]: value.load n[0] => _8 @ bb2[15]: fn test_store_value; _8 = (*_9); n[5]: free n[4] => _7 @ bb2[16]: fn test_store_value; _7 = free(move _8); } nodes_that_need_write = [] @@ -823,38 +818,38 @@ g { nodes_that_need_write = [3, 2, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_store_value_field; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn test_store_value_field; _1 = move _2 as *mut pointers::S (Misc); - n[2]: copy n[1] => _9 @ bb4[5]: fn test_store_value_field; _9 = _1; - n[3]: value.store n[2] => _5.*.2 @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); - n[4]: value.load _ => _10 @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); - n[5]: field.2 n[1] => _ @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; - n[6]: addr.store n[5] => _ @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; - n[7]: value.store n[4] => _1.*.2 @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; - n[8]: copy n[1] => _16 @ bb5[5]: fn test_store_value_field; _16 = _1; - n[9]: copy n[8] => _15 @ bb5[6]: fn test_store_value_field; _15 = move _16 as *mut libc::c_void (Misc); - n[10]: free n[9] => _14 @ bb5[8]: fn test_store_value_field; _14 = free(move _15); + n[0]: alloc _ => _2 @ bb1[2]: fn test_store_value_field; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn test_store_value_field; _1 = move _2 as *mut pointers::S (Misc); + n[2]: copy n[1] => _9 @ bb4[5]: fn test_store_value_field; _9 = _1; + n[3]: value.store n[2] => _5.*.2 @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); + n[4]: value.load n[0] => _10 @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); + n[5]: project.2@16 n[1] => _ @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; + n[6]: addr.store n[1] => _ @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; + n[7]: value.store n[4] => _1.*.2 @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; + n[8]: copy n[1] => _16 @ bb5[5]: fn test_store_value_field; _16 = _1; + n[9]: copy n[8] => _15 @ bb5[6]: fn test_store_value_field; _15 = move _16 as *mut libc::c_void (Misc); + n[10]: free n[9] => _14 @ bb5[8]: fn test_store_value_field; _14 = free(move _15); } -nodes_that_need_write = [6, 5, 1, 0] +nodes_that_need_write = [6, 1, 0] g { - n[0]: alloc _ => _6 @ bb3[2]: fn test_store_value_field; _6 = malloc(move _7); - n[1]: copy n[0] => _5 @ bb4[1]: fn test_store_value_field; _5 = move _6 as *mut pointers::S (Misc); - n[2]: field.2 n[1] => _ @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); - n[3]: addr.store n[2] => _ @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); - n[4]: field.2 n[1] => _10 @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); - n[5]: addr.load n[4] => _ @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); - n[6]: copy n[1] => _13 @ bb4[15]: fn test_store_value_field; _13 = _5; - n[7]: copy n[6] => _12 @ bb4[16]: fn test_store_value_field; _12 = move _13 as *mut libc::c_void (Misc); - n[8]: free n[7] => _11 @ bb4[18]: fn test_store_value_field; _11 = free(move _12); + n[0]: alloc _ => _6 @ bb3[2]: fn test_store_value_field; _6 = malloc(move _7); + n[1]: copy n[0] => _5 @ bb4[1]: fn test_store_value_field; _5 = move _6 as *mut pointers::S (Misc); + n[2]: project.2@16 n[1] => _ @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); + n[3]: addr.store n[1] => _ @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); + n[4]: project.2@16 n[1] => _ @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); + n[5]: addr.load n[1] => _ @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); + n[6]: copy n[1] => _13 @ bb4[15]: fn test_store_value_field; _13 = _5; + n[7]: copy n[6] => _12 @ bb4[16]: fn test_store_value_field; _12 = move _13 as *mut libc::c_void (Misc); + n[8]: free n[7] => _11 @ bb4[18]: fn test_store_value_field; _11 = free(move _12); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_load_value_store_value; _1 = malloc(move _2); - n[1]: value.load _ => _5 @ bb2[7]: fn test_load_value_store_value; _5 = (*_4); + n[1]: value.load n[0] => _5 @ bb2[7]: fn test_load_value_store_value; _5 = (*_4); n[2]: value.store n[1] => _4.* @ bb2[8]: fn test_load_value_store_value; (*_4) = move _5; - n[3]: value.load _ => _7 @ bb2[12]: fn test_load_value_store_value; _7 = (*_4); + n[3]: value.load n[0] => _7 @ bb2[12]: fn test_load_value_store_value; _7 = (*_4); n[4]: free n[3] => _6 @ bb2[13]: fn test_load_value_store_value; _6 = free(move _7); } nodes_that_need_write = [] @@ -951,17 +946,15 @@ g { nodes_that_need_write = [77, 76, 75, 68, 67, 66, 65, 64, 63, 56, 55, 54, 47, 46, 45, 35, 34, 33, 29, 28, 27, 17, 16, 15, 8, 7, 6, 2, 1, 0] g { - n[0]: &_4 _ => _ @ bb0[12]: fn test_ref_field; _8 = &raw mut _4; - n[1]: addr.store n[0] => _ @ bb0[11]: fn test_ref_field; _4 = pointers::S { field: const 0_i32, field2: const 0_u64, field3: move _5, field4: move _6 }; - n[2]: copy n[0] => _3 @ bb0[16]: fn test_ref_field; _3 = &mut (*_8); - n[3]: field.3 n[2] => _ @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); - n[4]: field.3 n[3] => _7 @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); - n[5]: addr.load n[4] => _ @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); - n[6]: field.3 n[2] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; - n[7]: field.3 n[6] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; - n[8]: addr.store n[7] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; + n[0]: &_4 _ => _ @ bb0[12]: fn test_ref_field; _8 = &raw mut _4; + n[1]: addr.store n[0] => _ @ bb0[11]: fn test_ref_field; _4 = pointers::S { field: const 0_i32, field2: const 0_u64, field3: move _5, field4: move _6 }; + n[2]: copy n[0] => _3 @ bb0[16]: fn test_ref_field; _3 = &mut (*_8); + n[3]: project.5@48 n[2] => _ @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); + n[4]: addr.load n[2] => _ @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); + n[5]: project.5@48 n[2] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; + n[6]: addr.store n[2] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; } -nodes_that_need_write = [8, 7, 6, 2, 1, 0] +nodes_that_need_write = [6, 2, 1, 0] g { n[0]: &_1 _ => _ @ bb0[2]: fn test_addr_taken; _10 = &raw mut _1; @@ -973,12 +966,12 @@ g { nodes_that_need_write = [1, 0] g { - n[0]: &_1 _ => _ @ bb0[0]: fn test_addr_taken_arg; _3 = &raw mut _1; - n[1]: field.2 n[0] => _ @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[2]: addr.store n[1] => _ @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[3]: copy n[0] => _2 @ bb0[3]: fn test_addr_taken_arg; _2 = &(*_3); + n[0]: &_1 _ => _ @ bb0[0]: fn test_addr_taken_arg; _3 = &raw mut _1; + n[1]: project.2@16 n[0] => _ @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[2]: addr.store n[0] => _ @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[3]: copy n[0] => _2 @ bb0[3]: fn test_addr_taken_arg; _2 = &(*_3); } -nodes_that_need_write = [2, 1, 0] +nodes_that_need_write = [2, 0] g { n[0]: &_3 _ => _ @ bb2[2]: fn test_addr_taken_loop; _20 = &raw mut _3; @@ -1029,6 +1022,6 @@ g { } nodes_that_need_write = [1, 0] -num_graphs = 67 -num_nodes = 759 +num_graphs = 66 +num_nodes = 755 diff --git a/pdg/src/snapshots/c2rust_pdg__tests__analysis_tests_misc_pdg_snapshot_release.snap b/pdg/src/snapshots/c2rust_pdg__tests__analysis_tests_misc_pdg_snapshot_release.snap index 9fb1a5cf68..c90c5ee8c4 100644 --- a/pdg/src/snapshots/c2rust_pdg__tests__analysis_tests_misc_pdg_snapshot_release.snap +++ b/pdg/src/snapshots/c2rust_pdg__tests__analysis_tests_misc_pdg_snapshot_release.snap @@ -1,5 +1,6 @@ --- source: pdg/src/main.rs +assertion_line: 384 expression: pdg --- g { @@ -19,13 +20,13 @@ nodes_that_need_write = [] g { n[0]: copy _ => _14 @ bb6[4]: fn main; _14 = null_mut(); n[1]: copy n[0] => _1 @ bb0[0]: fn once; _13 = once(move _14); - n[2]: int_to_ptr _ => _17 @ bb4[29]: fn simple; _17 = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[3]: value.store _ => _20.* @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); - n[4]: value.store _ => _17.* @ bb8[4]: fn fdevent_unregister; (*_17) = const 0_usize as *mut pointers::fdnode_st (PointerFromExposedAddress); - n[5]: int_to_ptr _ => _2 @ bb0[2]: fn test_ref_field; _2 = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[6]: int_to_ptr _ => _5 @ bb0[8]: fn test_ref_field; _5 = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[7]: int_to_ptr _ => _51 @ bb36[3]: fn main_0; _51 = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[8]: value.store _ => _3.*.2 @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[2]: int_to_ptr n[0] => _17 @ bb4[29]: fn simple; _17 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[3]: value.store n[0] => _20.* @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); + n[4]: value.store n[0] => _17.* @ bb8[4]: fn fdevent_unregister; (*_17) = const 0_usize as *mut pointers::fdnode_st (PointerFromExposedAddress); + n[5]: int_to_ptr n[0] => _2 @ bb0[2]: fn test_ref_field; _2 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[6]: int_to_ptr n[0] => _5 @ bb0[8]: fn test_ref_field; _5 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[7]: int_to_ptr n[0] => _51 @ bb36[3]: fn main_0; _51 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[8]: value.store n[0] => _3.*.2 @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); } nodes_that_need_write = [] @@ -44,75 +45,69 @@ g { nodes_that_need_write = [] g { - n[0]: alloc _ => _2 @ bb1[2]: fn simple; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn simple; _1 = move _2 as *mut pointers::S (Misc); - n[2]: copy n[1] => _5 @ bb2[5]: fn simple; _5 = _1; - n[3]: field.0 n[1] => _10 @ bb4[5]: fn simple; _10 = &raw const ((*_1).0: i32); - n[4]: copy n[2] => _24 @ bb5[5]: fn simple; _24 = _5; - n[5]: copy n[4] => _23 @ bb5[6]: fn simple; _23 = move _24 as *mut libc::c_void (Misc); - n[6]: free n[5] => _22 @ bb5[8]: fn simple; _22 = free(move _23); + n[0]: alloc _ => _2 @ bb1[2]: fn simple; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn simple; _1 = move _2 as *mut pointers::S (Misc); + n[2]: copy n[1] => _5 @ bb2[5]: fn simple; _5 = _1; + n[3]: project.0@0 n[1] => _10 @ bb4[5]: fn simple; _10 = &raw const ((*_1).0: i32); + n[4]: copy n[2] => _24 @ bb5[5]: fn simple; _24 = _5; + n[5]: copy n[4] => _23 @ bb5[6]: fn simple; _23 = move _24 as *mut libc::c_void (Misc); + n[6]: free n[5] => _22 @ bb5[8]: fn simple; _22 = free(move _23); } nodes_that_need_write = [] g { - n[0]: alloc _ => _7 @ bb3[2]: fn simple; _7 = malloc(move _8); - n[1]: copy n[0] => _6 @ bb4[1]: fn simple; _6 = move _7 as *mut pointers::S (Misc); - n[2]: copy n[1] => _11 @ bb4[8]: fn simple; _11 = _6; - n[3]: copy n[2] => _1 @ bb4[9]: fn simple; _1 = move _11; - n[4]: field.0 n[3] => _ @ bb4[11]: fn simple; ((*_1).0: i32) = const 10_i32; - n[5]: addr.store n[4] => _ @ bb4[11]: fn simple; ((*_1).0: i32) = const 10_i32; - n[6]: field.0 n[3] => _12 @ bb4[13]: fn simple; _12 = ((*_1).0: i32); - n[7]: addr.load n[6] => _ @ bb4[13]: fn simple; _12 = ((*_1).0: i32); - n[8]: field.0 n[1] => _ @ bb4[14]: fn simple; ((*_6).0: i32) = move _12; - n[9]: addr.store n[8] => _ @ bb4[14]: fn simple; ((*_6).0: i32) = move _12; - n[10]: field.1 n[3] => _ @ bb4[16]: fn simple; ((*_1).1: u64) = const 9_u64; - n[11]: addr.store n[10] => _ @ bb4[16]: fn simple; ((*_1).1: u64) = const 9_u64; - n[12]: field.0 n[3] => _13 @ bb4[18]: fn simple; _13 = ((*_1).0: i32); - n[13]: addr.load n[12] => _ @ bb4[18]: fn simple; _13 = ((*_1).0: i32); - n[14]: field.1 n[3] => _14 @ bb4[21]: fn simple; _14 = &raw const ((*_1).1: u64); - n[15]: copy n[14] => _14 @ bb4[21]: fn simple; _14 = &raw const ((*_1).1: u64); - n[16]: copy n[3] => _15 @ bb4[24]: fn simple; _15 = &raw const (*_1); - n[17]: field.2 n[3] => _ @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; - n[18]: addr.store n[17] => _ @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; - n[19]: value.store n[16] => _1.*.2 @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; - n[20]: field.3 n[1] => _ @ bb4[32]: fn simple; ((*_6).3: pointers::T) = move _16; - n[21]: addr.store n[20] => _ @ bb4[32]: fn simple; ((*_6).3: pointers::T) = move _16; - n[22]: addr.load n[1] => _ @ bb4[35]: fn simple; _18 = (*_6); - n[23]: addr.store n[3] => _ @ bb4[39]: fn simple; (*_1) = move _19; - n[24]: copy n[3] => _21 @ bb4[43]: fn simple; _21 = _1; - n[25]: copy n[24] => _2 @ bb0[0]: fn recur; _20 = recur(const 3_i32, move _21); - n[26]: copy n[25] => _12 @ bb7[9]: fn recur; _12 = _2; - n[27]: copy n[26] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _12); - n[28]: copy n[27] => _12 @ bb7[9]: fn recur; _12 = _2; - n[29]: copy n[28] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _12); - n[30]: copy n[29] => _12 @ bb7[9]: fn recur; _12 = _2; - n[31]: copy n[30] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _12); - n[32]: copy n[31] => _8 @ bb1[2]: fn recur; _8 = _2; - n[33]: copy n[32] => _7 @ bb1[3]: fn recur; _7 = move _8 as *mut libc::c_void (Misc); - n[34]: free n[33] => _0 @ bb1[5]: fn recur; _0 = free(move _7); - n[35]: copy n[31] => _13 @ bb8[4]: fn recur; _13 = _2; - n[36]: copy n[31] => _13 @ bb8[4]: fn recur; _13 = _2; - n[37]: copy n[31] => _13 @ bb8[4]: fn recur; _13 = _2; -} -nodes_that_need_write = [23, 21, 20, 18, 17, 11, 10, 9, 8, 5, 4, 3, 2, 1, 0] - -g { - n[0]: &_1 _ => _ @ bb4[5]: fn simple; _10 = &raw const ((*_1).0: i32); + n[0]: alloc _ => _7 @ bb3[2]: fn simple; _7 = malloc(move _8); + n[1]: copy n[0] => _6 @ bb4[1]: fn simple; _6 = move _7 as *mut pointers::S (Misc); + n[2]: copy n[1] => _11 @ bb4[8]: fn simple; _11 = _6; + n[3]: copy n[2] => _1 @ bb4[9]: fn simple; _1 = move _11; + n[4]: project.0@0 n[3] => _ @ bb4[11]: fn simple; ((*_1).0: i32) = const 10_i32; + n[5]: addr.store n[3] => _ @ bb4[11]: fn simple; ((*_1).0: i32) = const 10_i32; + n[6]: project.0@0 n[3] => _ @ bb4[13]: fn simple; _12 = ((*_1).0: i32); + n[7]: addr.load n[3] => _ @ bb4[13]: fn simple; _12 = ((*_1).0: i32); + n[8]: project.0@0 n[1] => _ @ bb4[14]: fn simple; ((*_6).0: i32) = move _12; + n[9]: addr.store n[1] => _ @ bb4[14]: fn simple; ((*_6).0: i32) = move _12; + n[10]: project.1@8 n[3] => _ @ bb4[16]: fn simple; ((*_1).1: u64) = const 9_u64; + n[11]: addr.store n[3] => _ @ bb4[16]: fn simple; ((*_1).1: u64) = const 9_u64; + n[12]: project.0@0 n[3] => _ @ bb4[18]: fn simple; _13 = ((*_1).0: i32); + n[13]: addr.load n[3] => _ @ bb4[18]: fn simple; _13 = ((*_1).0: i32); + n[14]: project.1@8 n[3] => _14 @ bb4[21]: fn simple; _14 = &raw const ((*_1).1: u64); + n[15]: copy n[3] => _15 @ bb4[24]: fn simple; _15 = &raw const (*_1); + n[16]: project.2@16 n[3] => _ @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; + n[17]: addr.store n[3] => _ @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; + n[18]: value.store n[15] => _1.*.2 @ bb4[25]: fn simple; ((*_1).2: *const pointers::S) = move _15; + n[19]: project.3@24 n[1] => _ @ bb4[32]: fn simple; ((*_6).3: pointers::T) = move _16; + n[20]: addr.store n[1] => _ @ bb4[32]: fn simple; ((*_6).3: pointers::T) = move _16; + n[21]: addr.load n[1] => _ @ bb4[35]: fn simple; _18 = (*_6); + n[22]: addr.store n[3] => _ @ bb4[39]: fn simple; (*_1) = move _19; + n[23]: copy n[3] => _21 @ bb4[43]: fn simple; _21 = _1; + n[24]: copy n[23] => _2 @ bb0[0]: fn recur; _20 = recur(const 3_i32, move _21); + n[25]: copy n[24] => _12 @ bb7[9]: fn recur; _12 = _2; + n[26]: copy n[25] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _12); + n[27]: copy n[26] => _12 @ bb7[9]: fn recur; _12 = _2; + n[28]: copy n[27] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _12); + n[29]: copy n[28] => _12 @ bb7[9]: fn recur; _12 = _2; + n[30]: copy n[29] => _2 @ bb0[0]: fn recur; _9 = recur(move _10, move _12); + n[31]: copy n[30] => _8 @ bb1[2]: fn recur; _8 = _2; + n[32]: copy n[31] => _7 @ bb1[3]: fn recur; _7 = move _8 as *mut libc::c_void (Misc); + n[33]: free n[32] => _0 @ bb1[5]: fn recur; _0 = free(move _7); + n[34]: copy n[30] => _13 @ bb8[4]: fn recur; _13 = _2; + n[35]: copy n[30] => _13 @ bb8[4]: fn recur; _13 = _2; + n[36]: copy n[30] => _13 @ bb8[4]: fn recur; _13 = _2; +} +nodes_that_need_write = [22, 20, 17, 11, 9, 5, 3, 2, 1, 0] + +g { + n[0]: alloc _ => _2 @ bb1[2]: fn exercise_allocator; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn exercise_allocator; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[5]: fn exercise_allocator; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[5]: fn exercise_allocator; ((*_1).0: i32) = const 10_i32; + n[4]: project.0@0 n[1] => _ @ bb2[18]: fn exercise_allocator; _10 = ((*_1).0: i32); + n[5]: addr.load n[1] => _ @ bb2[18]: fn exercise_allocator; _10 = ((*_1).0: i32); + n[6]: copy n[1] => _13 @ bb3[7]: fn exercise_allocator; _13 = _1; + n[7]: copy n[6] => _12 @ bb3[8]: fn exercise_allocator; _12 = move _13 as *mut libc::c_void (Misc); + n[8]: free n[7] => _11 @ bb5[2]: fn exercise_allocator; _11 = realloc(move _12, move _14); } -nodes_that_need_write = [] - -g { - n[0]: alloc _ => _2 @ bb1[2]: fn exercise_allocator; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn exercise_allocator; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[5]: fn exercise_allocator; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[5]: fn exercise_allocator; ((*_1).0: i32) = const 10_i32; - n[4]: field.0 n[1] => _10 @ bb2[18]: fn exercise_allocator; _10 = ((*_1).0: i32); - n[5]: addr.load n[4] => _ @ bb2[18]: fn exercise_allocator; _10 = ((*_1).0: i32); - n[6]: copy n[1] => _13 @ bb3[7]: fn exercise_allocator; _13 = _1; - n[7]: copy n[6] => _12 @ bb3[8]: fn exercise_allocator; _12 = move _13 as *mut libc::c_void (Misc); - n[8]: free n[7] => _11 @ bb5[2]: fn exercise_allocator; _11 = realloc(move _12, move _14); -} -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { n[0]: copy _ => _9 @ bb2[11]: fn exercise_allocator; _9 = const b"%i\n\x00"; @@ -120,72 +115,72 @@ g { n[2]: copy n[1] => _7 @ bb2[13]: fn exercise_allocator; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); n[3]: copy n[2] => _6 @ bb2[15]: fn exercise_allocator; _6 = move _7 as *const i8 (Misc); n[4]: copy n[3] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); - n[5]: copy _ => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; + n[5]: copy n[0] => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; n[6]: copy n[5] => _30 @ bb11[6]: fn exercise_allocator; _30 = &raw const (*_31); n[7]: copy n[6] => _29 @ bb11[7]: fn exercise_allocator; _29 = move _30 as *const u8 (Pointer(ArrayToPointer)); n[8]: copy n[7] => _28 @ bb11[9]: fn exercise_allocator; _28 = move _29 as *const i8 (Misc); n[9]: copy n[8] => _1 @ bb0[0]: fn printf; _27 = printf(move _28, move _32); - n[10]: copy _ => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; + n[10]: copy n[0] => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; n[11]: copy n[10] => _30 @ bb11[6]: fn exercise_allocator; _30 = &raw const (*_31); n[12]: copy n[11] => _29 @ bb11[7]: fn exercise_allocator; _29 = move _30 as *const u8 (Pointer(ArrayToPointer)); n[13]: copy n[12] => _28 @ bb11[9]: fn exercise_allocator; _28 = move _29 as *const i8 (Misc); n[14]: copy n[13] => _1 @ bb0[0]: fn printf; _27 = printf(move _28, move _32); - n[15]: copy _ => _60 @ bb28[5]: fn exercise_allocator; _60 = const b"%i\n\x00"; + n[15]: copy n[0] => _60 @ bb28[5]: fn exercise_allocator; _60 = const b"%i\n\x00"; n[16]: copy n[15] => _59 @ bb28[6]: fn exercise_allocator; _59 = &raw const (*_60); n[17]: copy n[16] => _58 @ bb28[7]: fn exercise_allocator; _58 = move _59 as *const u8 (Pointer(ArrayToPointer)); n[18]: copy n[17] => _57 @ bb28[9]: fn exercise_allocator; _57 = move _58 as *const i8 (Misc); n[19]: copy n[18] => _1 @ bb0[0]: fn printf; _56 = printf(move _57, move _61); - n[20]: copy _ => _60 @ bb28[5]: fn exercise_allocator; _60 = const b"%i\n\x00"; + n[20]: copy n[0] => _60 @ bb28[5]: fn exercise_allocator; _60 = const b"%i\n\x00"; n[21]: copy n[20] => _59 @ bb28[6]: fn exercise_allocator; _59 = &raw const (*_60); n[22]: copy n[21] => _58 @ bb28[7]: fn exercise_allocator; _58 = move _59 as *const u8 (Pointer(ArrayToPointer)); n[23]: copy n[22] => _57 @ bb28[9]: fn exercise_allocator; _57 = move _58 as *const i8 (Misc); n[24]: copy n[23] => _1 @ bb0[0]: fn printf; _56 = printf(move _57, move _61); - n[25]: copy _ => _60 @ bb28[5]: fn exercise_allocator; _60 = const b"%i\n\x00"; + n[25]: copy n[0] => _60 @ bb28[5]: fn exercise_allocator; _60 = const b"%i\n\x00"; n[26]: copy n[25] => _59 @ bb28[6]: fn exercise_allocator; _59 = &raw const (*_60); n[27]: copy n[26] => _58 @ bb28[7]: fn exercise_allocator; _58 = move _59 as *const u8 (Pointer(ArrayToPointer)); n[28]: copy n[27] => _57 @ bb28[9]: fn exercise_allocator; _57 = move _58 as *const i8 (Misc); n[29]: copy n[28] => _1 @ bb0[0]: fn printf; _56 = printf(move _57, move _61); - n[30]: copy _ => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; + n[30]: copy n[0] => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; n[31]: copy n[30] => _91 @ bb47[6]: fn exercise_allocator; _91 = &raw const (*_92); n[32]: copy n[31] => _90 @ bb47[7]: fn exercise_allocator; _90 = move _91 as *const u8 (Pointer(ArrayToPointer)); n[33]: copy n[32] => _89 @ bb47[9]: fn exercise_allocator; _89 = move _90 as *const i8 (Misc); n[34]: copy n[33] => _1 @ bb0[0]: fn printf; _88 = printf(move _89, move _93); - n[35]: copy _ => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; + n[35]: copy n[0] => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; n[36]: copy n[35] => _91 @ bb47[6]: fn exercise_allocator; _91 = &raw const (*_92); n[37]: copy n[36] => _90 @ bb47[7]: fn exercise_allocator; _90 = move _91 as *const u8 (Pointer(ArrayToPointer)); n[38]: copy n[37] => _89 @ bb47[9]: fn exercise_allocator; _89 = move _90 as *const i8 (Misc); n[39]: copy n[38] => _1 @ bb0[0]: fn printf; _88 = printf(move _89, move _93); - n[40]: copy _ => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; + n[40]: copy n[0] => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; n[41]: copy n[40] => _91 @ bb47[6]: fn exercise_allocator; _91 = &raw const (*_92); n[42]: copy n[41] => _90 @ bb47[7]: fn exercise_allocator; _90 = move _91 as *const u8 (Pointer(ArrayToPointer)); n[43]: copy n[42] => _89 @ bb47[9]: fn exercise_allocator; _89 = move _90 as *const i8 (Misc); n[44]: copy n[43] => _1 @ bb0[0]: fn printf; _88 = printf(move _89, move _93); - n[45]: copy _ => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; + n[45]: copy n[0] => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; n[46]: copy n[45] => _91 @ bb47[6]: fn exercise_allocator; _91 = &raw const (*_92); n[47]: copy n[46] => _90 @ bb47[7]: fn exercise_allocator; _90 = move _91 as *const u8 (Pointer(ArrayToPointer)); n[48]: copy n[47] => _89 @ bb47[9]: fn exercise_allocator; _89 = move _90 as *const i8 (Misc); n[49]: copy n[48] => _1 @ bb0[0]: fn printf; _88 = printf(move _89, move _93); - n[50]: copy _ => _9 @ bb2[11]: fn simple_analysis; _9 = const b"%i\n\x00"; + n[50]: copy n[0] => _9 @ bb2[11]: fn simple_analysis; _9 = const b"%i\n\x00"; n[51]: copy n[50] => _8 @ bb2[12]: fn simple_analysis; _8 = &raw const (*_9); n[52]: copy n[51] => _7 @ bb2[13]: fn simple_analysis; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); n[53]: copy n[52] => _6 @ bb2[15]: fn simple_analysis; _6 = move _7 as *const i8 (Misc); n[54]: copy n[53] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); - n[55]: copy _ => _6 @ bb0[5]: fn analysis2_helper; _6 = const b"%i\n\x00"; + n[55]: copy n[0] => _6 @ bb0[5]: fn analysis2_helper; _6 = const b"%i\n\x00"; n[56]: copy n[55] => _5 @ bb0[6]: fn analysis2_helper; _5 = &raw const (*_6); n[57]: copy n[56] => _4 @ bb0[7]: fn analysis2_helper; _4 = move _5 as *const u8 (Pointer(ArrayToPointer)); n[58]: copy n[57] => _3 @ bb0[9]: fn analysis2_helper; _3 = move _4 as *const i8 (Misc); n[59]: copy n[58] => _1 @ bb0[0]: fn printf; _2 = printf(move _3, move _7); - n[60]: copy _ => _9 @ bb2[11]: fn inter_function_analysis; _9 = const b"%i\n\x00"; + n[60]: copy n[0] => _9 @ bb2[11]: fn inter_function_analysis; _9 = const b"%i\n\x00"; n[61]: copy n[60] => _8 @ bb2[12]: fn inter_function_analysis; _8 = &raw const (*_9); n[62]: copy n[61] => _7 @ bb2[13]: fn inter_function_analysis; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); n[63]: copy n[62] => _6 @ bb2[15]: fn inter_function_analysis; _6 = move _7 as *const i8 (Misc); n[64]: copy n[63] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); - n[65]: copy _ => _11 @ bb2[18]: fn invalid; _11 = const b"%i\n\x00"; + n[65]: copy n[0] => _11 @ bb2[18]: fn invalid; _11 = const b"%i\n\x00"; n[66]: copy n[65] => _10 @ bb2[19]: fn invalid; _10 = &raw const (*_11); n[67]: copy n[66] => _9 @ bb2[20]: fn invalid; _9 = move _10 as *const u8 (Pointer(ArrayToPointer)); n[68]: copy n[67] => _8 @ bb2[22]: fn invalid; _8 = move _9 as *const i8 (Misc); n[69]: copy n[68] => _1 @ bb0[0]: fn printf; _7 = printf(move _8, move _12); - n[70]: copy _ => _17 @ bb3[9]: fn invalid; _17 = const b"%i\n\x00"; + n[70]: copy n[0] => _17 @ bb3[9]: fn invalid; _17 = const b"%i\n\x00"; n[71]: copy n[70] => _16 @ bb3[10]: fn invalid; _16 = &raw const (*_17); n[72]: copy n[71] => _15 @ bb3[11]: fn invalid; _15 = move _16 as *const u8 (Pointer(ArrayToPointer)); n[73]: copy n[72] => _14 @ bb3[13]: fn invalid; _14 = move _15 as *const i8 (Misc); @@ -194,152 +189,152 @@ g { nodes_that_need_write = [] g { - n[0]: alloc _ => _11 @ bb5[2]: fn exercise_allocator; _11 = realloc(move _12, move _14); - n[1]: copy n[0] => _1 @ bb6[2]: fn exercise_allocator; _1 = move _11 as *mut pointers::S (Misc); - n[2]: copy n[1] => _19 @ bb6[6]: fn exercise_allocator; _19 = _1; - n[3]: offset[0] n[2] => _18 @ bb6[7]: fn exercise_allocator; _18 = offset(move _19, const 0_isize); - n[4]: field.0 n[3] => _ @ bb7[1]: fn exercise_allocator; ((*_18).0: i32) = const 10_i32; - n[5]: addr.store n[4] => _ @ bb7[1]: fn exercise_allocator; ((*_18).0: i32) = const 10_i32; - n[6]: copy n[1] => _21 @ bb7[5]: fn exercise_allocator; _21 = _1; - n[7]: offset[1] n[6] => _20 @ bb7[6]: fn exercise_allocator; _20 = offset(move _21, const 1_isize); - n[8]: field.0 n[7] => _ @ bb8[1]: fn exercise_allocator; ((*_20).0: i32) = const 11_i32; - n[9]: addr.store n[8] => _ @ bb8[1]: fn exercise_allocator; ((*_20).0: i32) = const 11_i32; - n[10]: copy n[1] => _34 @ bb11[14]: fn exercise_allocator; _34 = _1; - n[11]: offset[0] n[10] => _33 @ bb11[20]: fn exercise_allocator; _33 = offset(move _34, move _35); - n[12]: field.0 n[11] => _32 @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); - n[13]: addr.load n[12] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); - n[14]: copy n[1] => _34 @ bb11[14]: fn exercise_allocator; _34 = _1; - n[15]: offset[1] n[14] => _33 @ bb11[20]: fn exercise_allocator; _33 = offset(move _34, move _35); - n[16]: field.0 n[15] => _32 @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); - n[17]: addr.load n[16] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); - n[18]: copy n[1] => _42 @ bb20[6]: fn exercise_allocator; _42 = _1; - n[19]: copy n[18] => _41 @ bb20[7]: fn exercise_allocator; _41 = move _42 as *mut libc::c_void (Misc); - n[20]: copy n[1] => _4 @ bb0[1]: fn reallocarray; _4 = _1; - n[21]: copy n[20] => _1 @ bb0[10]: fn reallocarray; _0 = const pointers::REALLOC(move _4, move _5); - n[22]: free n[19] => _40 @ bb21[2]: fn exercise_allocator; _40 = reallocarray(move _41, move _43, move _44); -} -nodes_that_need_write = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - -g { - n[0]: alloc _ => _40 @ bb21[2]: fn exercise_allocator; _40 = reallocarray(move _41, move _43, move _44); - n[1]: copy n[0] => _1 @ bb22[3]: fn exercise_allocator; _1 = move _40 as *mut pointers::S (Misc); - n[2]: copy n[1] => _47 @ bb22[7]: fn exercise_allocator; _47 = _1; - n[3]: offset[0] n[2] => _46 @ bb22[8]: fn exercise_allocator; _46 = offset(move _47, const 0_isize); - n[4]: field.0 n[3] => _ @ bb23[1]: fn exercise_allocator; ((*_46).0: i32) = const 10_i32; - n[5]: addr.store n[4] => _ @ bb23[1]: fn exercise_allocator; ((*_46).0: i32) = const 10_i32; - n[6]: copy n[1] => _49 @ bb23[5]: fn exercise_allocator; _49 = _1; - n[7]: offset[1] n[6] => _48 @ bb23[6]: fn exercise_allocator; _48 = offset(move _49, const 1_isize); - n[8]: field.0 n[7] => _ @ bb24[1]: fn exercise_allocator; ((*_48).0: i32) = const 11_i32; - n[9]: addr.store n[8] => _ @ bb24[1]: fn exercise_allocator; ((*_48).0: i32) = const 11_i32; - n[10]: copy n[1] => _51 @ bb24[5]: fn exercise_allocator; _51 = _1; - n[11]: offset[2] n[10] => _50 @ bb24[6]: fn exercise_allocator; _50 = offset(move _51, const 2_isize); - n[12]: field.0 n[11] => _ @ bb25[1]: fn exercise_allocator; ((*_50).0: i32) = const 12_i32; - n[13]: addr.store n[12] => _ @ bb25[1]: fn exercise_allocator; ((*_50).0: i32) = const 12_i32; - n[14]: copy n[1] => _63 @ bb28[14]: fn exercise_allocator; _63 = _1; - n[15]: offset[0] n[14] => _62 @ bb28[20]: fn exercise_allocator; _62 = offset(move _63, move _64); - n[16]: field.0 n[15] => _61 @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); - n[17]: addr.load n[16] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); - n[18]: copy n[1] => _63 @ bb28[14]: fn exercise_allocator; _63 = _1; - n[19]: offset[1] n[18] => _62 @ bb28[20]: fn exercise_allocator; _62 = offset(move _63, move _64); - n[20]: field.0 n[19] => _61 @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); - n[21]: addr.load n[20] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); - n[22]: copy n[1] => _63 @ bb28[14]: fn exercise_allocator; _63 = _1; - n[23]: offset[2] n[22] => _62 @ bb28[20]: fn exercise_allocator; _62 = offset(move _63, move _64); - n[24]: field.0 n[23] => _61 @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); - n[25]: addr.load n[24] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); - n[26]: copy n[1] => _71 @ bb37[6]: fn exercise_allocator; _71 = _1; - n[27]: copy n[26] => _70 @ bb37[7]: fn exercise_allocator; _70 = move _71 as *mut libc::c_void (Misc); - n[28]: free n[27] => _69 @ bb37[9]: fn exercise_allocator; _69 = free(move _70); -} -nodes_that_need_write = [13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - -g { - n[0]: alloc _ => _72 @ bb39[2]: fn exercise_allocator; _72 = calloc(move _73, move _74); - n[1]: copy n[0] => _1 @ bb40[2]: fn exercise_allocator; _1 = move _72 as *mut pointers::S (Misc); - n[2]: copy n[1] => _77 @ bb40[6]: fn exercise_allocator; _77 = _1; - n[3]: offset[0] n[2] => _76 @ bb40[7]: fn exercise_allocator; _76 = offset(move _77, const 0_isize); - n[4]: field.0 n[3] => _ @ bb41[1]: fn exercise_allocator; ((*_76).0: i32) = const 10_i32; - n[5]: addr.store n[4] => _ @ bb41[1]: fn exercise_allocator; ((*_76).0: i32) = const 10_i32; - n[6]: copy n[1] => _79 @ bb41[5]: fn exercise_allocator; _79 = _1; - n[7]: offset[1] n[6] => _78 @ bb41[6]: fn exercise_allocator; _78 = offset(move _79, const 1_isize); - n[8]: field.0 n[7] => _ @ bb42[1]: fn exercise_allocator; ((*_78).0: i32) = const 11_i32; - n[9]: addr.store n[8] => _ @ bb42[1]: fn exercise_allocator; ((*_78).0: i32) = const 11_i32; - n[10]: copy n[1] => _81 @ bb42[5]: fn exercise_allocator; _81 = _1; - n[11]: offset[2] n[10] => _80 @ bb42[6]: fn exercise_allocator; _80 = offset(move _81, const 2_isize); - n[12]: field.0 n[11] => _ @ bb43[1]: fn exercise_allocator; ((*_80).0: i32) = const 12_i32; - n[13]: addr.store n[12] => _ @ bb43[1]: fn exercise_allocator; ((*_80).0: i32) = const 12_i32; - n[14]: copy n[1] => _83 @ bb43[5]: fn exercise_allocator; _83 = _1; - n[15]: offset[3] n[14] => _82 @ bb43[6]: fn exercise_allocator; _82 = offset(move _83, const 3_isize); - n[16]: field.0 n[15] => _ @ bb44[1]: fn exercise_allocator; ((*_82).0: i32) = const 13_i32; - n[17]: addr.store n[16] => _ @ bb44[1]: fn exercise_allocator; ((*_82).0: i32) = const 13_i32; - n[18]: copy n[1] => _95 @ bb47[14]: fn exercise_allocator; _95 = _1; - n[19]: offset[0] n[18] => _94 @ bb47[20]: fn exercise_allocator; _94 = offset(move _95, move _96); - n[20]: field.0 n[19] => _93 @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); - n[21]: addr.load n[20] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); - n[22]: copy n[1] => _95 @ bb47[14]: fn exercise_allocator; _95 = _1; - n[23]: offset[1] n[22] => _94 @ bb47[20]: fn exercise_allocator; _94 = offset(move _95, move _96); - n[24]: field.0 n[23] => _93 @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); - n[25]: addr.load n[24] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); - n[26]: copy n[1] => _95 @ bb47[14]: fn exercise_allocator; _95 = _1; - n[27]: offset[2] n[26] => _94 @ bb47[20]: fn exercise_allocator; _94 = offset(move _95, move _96); - n[28]: field.0 n[27] => _93 @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); - n[29]: addr.load n[28] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); - n[30]: copy n[1] => _95 @ bb47[14]: fn exercise_allocator; _95 = _1; - n[31]: offset[3] n[30] => _94 @ bb47[20]: fn exercise_allocator; _94 = offset(move _95, move _96); - n[32]: field.0 n[31] => _93 @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); - n[33]: addr.load n[32] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); - n[34]: copy n[1] => _103 @ bb56[6]: fn exercise_allocator; _103 = _1; - n[35]: copy n[34] => _102 @ bb56[7]: fn exercise_allocator; _102 = move _103 as *mut libc::c_void (Misc); - n[36]: free n[35] => _101 @ bb56[9]: fn exercise_allocator; _101 = free(move _102); -} -nodes_that_need_write = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0] - -g { - n[0]: alloc _ => _2 @ bb1[2]: fn simple_analysis; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn simple_analysis; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[5]: fn simple_analysis; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[5]: fn simple_analysis; ((*_1).0: i32) = const 10_i32; - n[4]: field.0 n[1] => _10 @ bb2[18]: fn simple_analysis; _10 = ((*_1).0: i32); - n[5]: addr.load n[4] => _ @ bb2[18]: fn simple_analysis; _10 = ((*_1).0: i32); - n[6]: copy n[1] => _13 @ bb3[7]: fn simple_analysis; _13 = _1; - n[7]: copy n[6] => _12 @ bb3[8]: fn simple_analysis; _12 = move _13 as *mut libc::c_void (Misc); - n[8]: free n[7] => _11 @ bb3[10]: fn simple_analysis; _11 = free(move _12); + n[0]: alloc _ => _11 @ bb5[2]: fn exercise_allocator; _11 = realloc(move _12, move _14); + n[1]: copy n[0] => _1 @ bb6[2]: fn exercise_allocator; _1 = move _11 as *mut pointers::S (Misc); + n[2]: copy n[1] => _19 @ bb6[6]: fn exercise_allocator; _19 = _1; + n[3]: offset[0] n[2] => _18 @ bb6[7]: fn exercise_allocator; _18 = offset(move _19, const 0_isize); + n[4]: project.0@0 n[3] => _ @ bb7[1]: fn exercise_allocator; ((*_18).0: i32) = const 10_i32; + n[5]: addr.store n[3] => _ @ bb7[1]: fn exercise_allocator; ((*_18).0: i32) = const 10_i32; + n[6]: copy n[1] => _21 @ bb7[5]: fn exercise_allocator; _21 = _1; + n[7]: offset[1] n[6] => _20 @ bb7[6]: fn exercise_allocator; _20 = offset(move _21, const 1_isize); + n[8]: project.0@0 n[7] => _ @ bb8[1]: fn exercise_allocator; ((*_20).0: i32) = const 11_i32; + n[9]: addr.store n[7] => _ @ bb8[1]: fn exercise_allocator; ((*_20).0: i32) = const 11_i32; + n[10]: copy n[1] => _34 @ bb11[14]: fn exercise_allocator; _34 = _1; + n[11]: offset[0] n[10] => _33 @ bb11[20]: fn exercise_allocator; _33 = offset(move _34, move _35); + n[12]: project.0@0 n[11] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); + n[13]: addr.load n[11] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); + n[14]: copy n[1] => _34 @ bb11[14]: fn exercise_allocator; _34 = _1; + n[15]: offset[1] n[14] => _33 @ bb11[20]: fn exercise_allocator; _33 = offset(move _34, move _35); + n[16]: project.0@0 n[15] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); + n[17]: addr.load n[15] => _ @ bb13[2]: fn exercise_allocator; _32 = ((*_33).0: i32); + n[18]: copy n[1] => _42 @ bb20[6]: fn exercise_allocator; _42 = _1; + n[19]: copy n[18] => _41 @ bb20[7]: fn exercise_allocator; _41 = move _42 as *mut libc::c_void (Misc); + n[20]: copy n[1] => _4 @ bb0[1]: fn reallocarray; _4 = _1; + n[21]: copy n[20] => _1 @ bb0[10]: fn reallocarray; _0 = const pointers::REALLOC(move _4, move _5); + n[22]: free n[19] => _40 @ bb21[2]: fn exercise_allocator; _40 = reallocarray(move _41, move _43, move _44); +} +nodes_that_need_write = [9, 7, 6, 5, 3, 2, 1, 0] + +g { + n[0]: alloc _ => _40 @ bb21[2]: fn exercise_allocator; _40 = reallocarray(move _41, move _43, move _44); + n[1]: copy n[0] => _1 @ bb22[3]: fn exercise_allocator; _1 = move _40 as *mut pointers::S (Misc); + n[2]: copy n[1] => _47 @ bb22[7]: fn exercise_allocator; _47 = _1; + n[3]: offset[0] n[2] => _46 @ bb22[8]: fn exercise_allocator; _46 = offset(move _47, const 0_isize); + n[4]: project.0@0 n[3] => _ @ bb23[1]: fn exercise_allocator; ((*_46).0: i32) = const 10_i32; + n[5]: addr.store n[3] => _ @ bb23[1]: fn exercise_allocator; ((*_46).0: i32) = const 10_i32; + n[6]: copy n[1] => _49 @ bb23[5]: fn exercise_allocator; _49 = _1; + n[7]: offset[1] n[6] => _48 @ bb23[6]: fn exercise_allocator; _48 = offset(move _49, const 1_isize); + n[8]: project.0@0 n[7] => _ @ bb24[1]: fn exercise_allocator; ((*_48).0: i32) = const 11_i32; + n[9]: addr.store n[7] => _ @ bb24[1]: fn exercise_allocator; ((*_48).0: i32) = const 11_i32; + n[10]: copy n[1] => _51 @ bb24[5]: fn exercise_allocator; _51 = _1; + n[11]: offset[2] n[10] => _50 @ bb24[6]: fn exercise_allocator; _50 = offset(move _51, const 2_isize); + n[12]: project.0@0 n[11] => _ @ bb25[1]: fn exercise_allocator; ((*_50).0: i32) = const 12_i32; + n[13]: addr.store n[11] => _ @ bb25[1]: fn exercise_allocator; ((*_50).0: i32) = const 12_i32; + n[14]: copy n[1] => _63 @ bb28[14]: fn exercise_allocator; _63 = _1; + n[15]: offset[0] n[14] => _62 @ bb28[20]: fn exercise_allocator; _62 = offset(move _63, move _64); + n[16]: project.0@0 n[15] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); + n[17]: addr.load n[15] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); + n[18]: copy n[1] => _63 @ bb28[14]: fn exercise_allocator; _63 = _1; + n[19]: offset[1] n[18] => _62 @ bb28[20]: fn exercise_allocator; _62 = offset(move _63, move _64); + n[20]: project.0@0 n[19] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); + n[21]: addr.load n[19] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); + n[22]: copy n[1] => _63 @ bb28[14]: fn exercise_allocator; _63 = _1; + n[23]: offset[2] n[22] => _62 @ bb28[20]: fn exercise_allocator; _62 = offset(move _63, move _64); + n[24]: project.0@0 n[23] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); + n[25]: addr.load n[23] => _ @ bb30[2]: fn exercise_allocator; _61 = ((*_62).0: i32); + n[26]: copy n[1] => _71 @ bb37[6]: fn exercise_allocator; _71 = _1; + n[27]: copy n[26] => _70 @ bb37[7]: fn exercise_allocator; _70 = move _71 as *mut libc::c_void (Misc); + n[28]: free n[27] => _69 @ bb37[9]: fn exercise_allocator; _69 = free(move _70); +} +nodes_that_need_write = [13, 11, 10, 9, 7, 6, 5, 3, 2, 1, 0] + +g { + n[0]: alloc _ => _72 @ bb39[2]: fn exercise_allocator; _72 = calloc(move _73, move _74); + n[1]: copy n[0] => _1 @ bb40[2]: fn exercise_allocator; _1 = move _72 as *mut pointers::S (Misc); + n[2]: copy n[1] => _77 @ bb40[6]: fn exercise_allocator; _77 = _1; + n[3]: offset[0] n[2] => _76 @ bb40[7]: fn exercise_allocator; _76 = offset(move _77, const 0_isize); + n[4]: project.0@0 n[3] => _ @ bb41[1]: fn exercise_allocator; ((*_76).0: i32) = const 10_i32; + n[5]: addr.store n[3] => _ @ bb41[1]: fn exercise_allocator; ((*_76).0: i32) = const 10_i32; + n[6]: copy n[1] => _79 @ bb41[5]: fn exercise_allocator; _79 = _1; + n[7]: offset[1] n[6] => _78 @ bb41[6]: fn exercise_allocator; _78 = offset(move _79, const 1_isize); + n[8]: project.0@0 n[7] => _ @ bb42[1]: fn exercise_allocator; ((*_78).0: i32) = const 11_i32; + n[9]: addr.store n[7] => _ @ bb42[1]: fn exercise_allocator; ((*_78).0: i32) = const 11_i32; + n[10]: copy n[1] => _81 @ bb42[5]: fn exercise_allocator; _81 = _1; + n[11]: offset[2] n[10] => _80 @ bb42[6]: fn exercise_allocator; _80 = offset(move _81, const 2_isize); + n[12]: project.0@0 n[11] => _ @ bb43[1]: fn exercise_allocator; ((*_80).0: i32) = const 12_i32; + n[13]: addr.store n[11] => _ @ bb43[1]: fn exercise_allocator; ((*_80).0: i32) = const 12_i32; + n[14]: copy n[1] => _83 @ bb43[5]: fn exercise_allocator; _83 = _1; + n[15]: offset[3] n[14] => _82 @ bb43[6]: fn exercise_allocator; _82 = offset(move _83, const 3_isize); + n[16]: project.0@0 n[15] => _ @ bb44[1]: fn exercise_allocator; ((*_82).0: i32) = const 13_i32; + n[17]: addr.store n[15] => _ @ bb44[1]: fn exercise_allocator; ((*_82).0: i32) = const 13_i32; + n[18]: copy n[1] => _95 @ bb47[14]: fn exercise_allocator; _95 = _1; + n[19]: offset[0] n[18] => _94 @ bb47[20]: fn exercise_allocator; _94 = offset(move _95, move _96); + n[20]: project.0@0 n[19] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); + n[21]: addr.load n[19] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); + n[22]: copy n[1] => _95 @ bb47[14]: fn exercise_allocator; _95 = _1; + n[23]: offset[1] n[22] => _94 @ bb47[20]: fn exercise_allocator; _94 = offset(move _95, move _96); + n[24]: project.0@0 n[23] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); + n[25]: addr.load n[23] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); + n[26]: copy n[1] => _95 @ bb47[14]: fn exercise_allocator; _95 = _1; + n[27]: offset[2] n[26] => _94 @ bb47[20]: fn exercise_allocator; _94 = offset(move _95, move _96); + n[28]: project.0@0 n[27] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); + n[29]: addr.load n[27] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); + n[30]: copy n[1] => _95 @ bb47[14]: fn exercise_allocator; _95 = _1; + n[31]: offset[3] n[30] => _94 @ bb47[20]: fn exercise_allocator; _94 = offset(move _95, move _96); + n[32]: project.0@0 n[31] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); + n[33]: addr.load n[31] => _ @ bb49[2]: fn exercise_allocator; _93 = ((*_94).0: i32); + n[34]: copy n[1] => _103 @ bb56[6]: fn exercise_allocator; _103 = _1; + n[35]: copy n[34] => _102 @ bb56[7]: fn exercise_allocator; _102 = move _103 as *mut libc::c_void (Misc); + n[36]: free n[35] => _101 @ bb56[9]: fn exercise_allocator; _101 = free(move _102); +} +nodes_that_need_write = [17, 15, 14, 13, 11, 10, 9, 7, 6, 5, 3, 2, 1, 0] + +g { + n[0]: alloc _ => _2 @ bb1[2]: fn simple_analysis; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn simple_analysis; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[5]: fn simple_analysis; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[5]: fn simple_analysis; ((*_1).0: i32) = const 10_i32; + n[4]: project.0@0 n[1] => _ @ bb2[18]: fn simple_analysis; _10 = ((*_1).0: i32); + n[5]: addr.load n[1] => _ @ bb2[18]: fn simple_analysis; _10 = ((*_1).0: i32); + n[6]: copy n[1] => _13 @ bb3[7]: fn simple_analysis; _13 = _1; + n[7]: copy n[6] => _12 @ bb3[8]: fn simple_analysis; _12 = move _13 as *mut libc::c_void (Misc); + n[8]: free n[7] => _11 @ bb3[10]: fn simple_analysis; _11 = free(move _12); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn analysis2; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn analysis2; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[5]: fn analysis2; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[5]: fn analysis2; ((*_1).0: i32) = const 10_i32; - n[4]: copy n[1] => _6 @ bb2[8]: fn analysis2; _6 = _1; - n[5]: copy n[4] => _1 @ bb0[0]: fn analysis2_helper; _5 = analysis2_helper(move _6); - n[6]: field.0 n[5] => _7 @ bb0[12]: fn analysis2_helper; _7 = ((*_1).0: i32); - n[7]: addr.load n[6] => _ @ bb0[12]: fn analysis2_helper; _7 = ((*_1).0: i32); - n[8]: copy n[5] => _9 @ bb3[5]: fn analysis2; _9 = _1; - n[9]: copy n[8] => _8 @ bb3[6]: fn analysis2; _8 = move _9 as *mut libc::c_void (Misc); - n[10]: free n[9] => _7 @ bb3[8]: fn analysis2; _7 = free(move _8); + n[0]: alloc _ => _2 @ bb1[2]: fn analysis2; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn analysis2; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[5]: fn analysis2; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[5]: fn analysis2; ((*_1).0: i32) = const 10_i32; + n[4]: copy n[1] => _6 @ bb2[8]: fn analysis2; _6 = _1; + n[5]: copy n[4] => _1 @ bb0[0]: fn analysis2_helper; _5 = analysis2_helper(move _6); + n[6]: project.0@0 n[5] => _ @ bb0[12]: fn analysis2_helper; _7 = ((*_1).0: i32); + n[7]: addr.load n[5] => _ @ bb0[12]: fn analysis2_helper; _7 = ((*_1).0: i32); + n[8]: copy n[5] => _9 @ bb3[5]: fn analysis2; _9 = _1; + n[9]: copy n[8] => _8 @ bb3[6]: fn analysis2; _8 = move _9 as *mut libc::c_void (Misc); + n[10]: free n[9] => _7 @ bb3[8]: fn analysis2; _7 = free(move _8); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _0 @ bb0[2]: fn malloc_wrapper; _0 = malloc(move _3); - n[1]: copy n[0] => _2 @ bb1[2]: fn inter_function_analysis; _2 = malloc_wrapper(move _3); - n[2]: copy n[1] => _1 @ bb2[1]: fn inter_function_analysis; _1 = move _2 as *mut pointers::S (Misc); - n[3]: field.0 n[2] => _ @ bb2[5]: fn inter_function_analysis; ((*_1).0: i32) = const 11_i32; - n[4]: addr.store n[3] => _ @ bb2[5]: fn inter_function_analysis; ((*_1).0: i32) = const 11_i32; - n[5]: field.0 n[2] => _10 @ bb2[18]: fn inter_function_analysis; _10 = ((*_1).0: i32); - n[6]: addr.load n[5] => _ @ bb2[18]: fn inter_function_analysis; _10 = ((*_1).0: i32); - n[7]: copy n[2] => _13 @ bb3[7]: fn inter_function_analysis; _13 = _1; - n[8]: copy n[7] => _12 @ bb3[8]: fn inter_function_analysis; _12 = move _13 as *mut libc::c_void (Misc); - n[9]: free n[8] => _11 @ bb3[10]: fn inter_function_analysis; _11 = free(move _12); + n[0]: alloc _ => _0 @ bb0[2]: fn malloc_wrapper; _0 = malloc(move _3); + n[1]: copy n[0] => _2 @ bb1[2]: fn inter_function_analysis; _2 = malloc_wrapper(move _3); + n[2]: copy n[1] => _1 @ bb2[1]: fn inter_function_analysis; _1 = move _2 as *mut pointers::S (Misc); + n[3]: project.0@0 n[2] => _ @ bb2[5]: fn inter_function_analysis; ((*_1).0: i32) = const 11_i32; + n[4]: addr.store n[2] => _ @ bb2[5]: fn inter_function_analysis; ((*_1).0: i32) = const 11_i32; + n[5]: project.0@0 n[2] => _ @ bb2[18]: fn inter_function_analysis; _10 = ((*_1).0: i32); + n[6]: addr.load n[2] => _ @ bb2[18]: fn inter_function_analysis; _10 = ((*_1).0: i32); + n[7]: copy n[2] => _13 @ bb3[7]: fn inter_function_analysis; _13 = _1; + n[8]: copy n[7] => _12 @ bb3[8]: fn inter_function_analysis; _12 = move _13 as *mut libc::c_void (Misc); + n[9]: free n[8] => _11 @ bb3[10]: fn inter_function_analysis; _11 = free(move _12); } -nodes_that_need_write = [4, 3, 2, 1, 0] +nodes_that_need_write = [4, 2, 1, 0] g { n[0]: alloc _ => _2 @ bb1[2]: fn no_owner; _2 = malloc(move _3); n[1]: value.store n[0] => _5.* @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); - n[2]: value.load _ => _12 @ bb6[6]: fn main_0; _12 = (*_13); + n[2]: value.load n[0] => _12 @ bb6[6]: fn main_0; _12 = (*_13); n[3]: copy n[2] => _11 @ bb6[7]: fn main_0; _11 = move _12 as *mut libc::c_void (Misc); n[4]: free n[3] => _10 @ bb6[9]: fn main_0; _10 = free(move _11); } @@ -348,45 +343,47 @@ nodes_that_need_write = [] g { n[0]: copy _ => _5 @ bb2[2]: fn no_owner; _5 = const {alloc8: *mut *mut pointers::S}; n[1]: addr.store n[0] => _ @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); - n[2]: copy _ => _13 @ bb6[5]: fn main_0; _13 = const {alloc8: *mut *mut pointers::S}; + n[2]: copy n[0] => _13 @ bb6[5]: fn main_0; _13 = const {alloc8: *mut *mut pointers::S}; n[3]: addr.load n[2] => _ @ bb6[6]: fn main_0; _12 = (*_13); - n[4]: copy _ => _5 @ bb2[2]: fn no_owner; _5 = const {alloc8: *mut *mut pointers::S}; + n[4]: copy n[0] => _5 @ bb2[2]: fn no_owner; _5 = const {alloc8: *mut *mut pointers::S}; n[5]: addr.store n[4] => _ @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); - n[6]: copy _ => _12 @ bb3[4]: fn no_owner; _12 = const {alloc8: *mut *mut pointers::S}; + n[6]: copy n[0] => _12 @ bb3[4]: fn no_owner; _12 = const {alloc8: *mut *mut pointers::S}; n[7]: addr.load n[6] => _ @ bb3[5]: fn no_owner; _11 = (*_12); - n[8]: copy _ => _6 @ bb2[9]: fn invalid; _6 = const {alloc8: *mut *mut pointers::S}; + n[8]: copy n[0] => _6 @ bb2[9]: fn invalid; _6 = const {alloc8: *mut *mut pointers::S}; n[9]: addr.store n[8] => _ @ bb2[10]: fn invalid; (*_6) = move _5; - n[10]: copy _ => _19 @ bb3[17]: fn invalid; _19 = const {alloc8: *mut *mut pointers::S}; - n[11]: field.0 n[10] => _18 @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); - n[12]: addr.load n[11] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); - n[13]: copy _ => _20 @ bb4[6]: fn invalid; _20 = const {alloc8: *mut *mut pointers::S}; - n[14]: addr.store n[13] => _ @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); + n[10]: copy n[0] => _19 @ bb3[17]: fn invalid; _19 = const {alloc8: *mut *mut pointers::S}; + n[11]: addr.load n[10] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[12]: copy n[0] => _20 @ bb4[6]: fn invalid; _20 = const {alloc8: *mut *mut pointers::S}; + n[13]: addr.store n[12] => _ @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); } -nodes_that_need_write = [14, 13, 9, 8, 5, 4, 1, 0] +nodes_that_need_write = [13, 12, 9, 8, 5, 4, 1, 0] g { n[0]: alloc _ => _2 @ bb1[2]: fn no_owner; _2 = malloc(move _3); n[1]: value.store n[0] => _5.* @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); - n[2]: value.load _ => _11 @ bb3[5]: fn no_owner; _11 = (*_12); + n[2]: value.load n[0] => _11 @ bb3[5]: fn no_owner; _11 = (*_12); n[3]: copy n[2] => _10 @ bb3[6]: fn no_owner; _10 = move _11 as *mut libc::c_void (Misc); n[4]: free n[3] => _9 @ bb3[8]: fn no_owner; _9 = free(move _10); } nodes_that_need_write = [] g { - n[0]: alloc _ => _2 @ bb1[2]: fn invalid; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn invalid; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[5]: fn invalid; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[5]: fn invalid; ((*_1).0: i32) = const 10_i32; - n[4]: copy n[1] => _5 @ bb2[7]: fn invalid; _5 = _1; - n[5]: value.store n[4] => _6.* @ bb2[10]: fn invalid; (*_6) = move _5; - n[6]: field.0 n[1] => _12 @ bb2[25]: fn invalid; _12 = ((*_1).0: i32); - n[7]: addr.load n[6] => _ @ bb2[25]: fn invalid; _12 = ((*_1).0: i32); - n[8]: copy n[1] => _23 @ bb4[12]: fn invalid; _23 = _1; - n[9]: copy n[8] => _22 @ bb4[13]: fn invalid; _22 = move _23 as *mut libc::c_void (Misc); - n[10]: free n[9] => _21 @ bb4[15]: fn invalid; _21 = free(move _22); + n[0]: alloc _ => _2 @ bb1[2]: fn invalid; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn invalid; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[5]: fn invalid; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[5]: fn invalid; ((*_1).0: i32) = const 10_i32; + n[4]: copy n[1] => _5 @ bb2[7]: fn invalid; _5 = _1; + n[5]: value.store n[4] => _6.* @ bb2[10]: fn invalid; (*_6) = move _5; + n[6]: project.0@0 n[1] => _ @ bb2[25]: fn invalid; _12 = ((*_1).0: i32); + n[7]: addr.load n[1] => _ @ bb2[25]: fn invalid; _12 = ((*_1).0: i32); + n[8]: value.load n[6] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[9]: project.0@0 n[6] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[10]: addr.load n[9] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[11]: copy n[1] => _23 @ bb4[12]: fn invalid; _23 = _1; + n[12]: copy n[11] => _22 @ bb4[13]: fn invalid; _22 = move _23 as *mut libc::c_void (Misc); + n[13]: free n[12] => _21 @ bb4[15]: fn invalid; _21 = free(move _22); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { n[0]: &_1 _ => _ @ bb0[2]: fn testing; _8 = &raw mut _1; @@ -408,30 +405,30 @@ g { nodes_that_need_write = [3, 2, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn simple1; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn simple1; _1 = move _2 as *mut pointers::S (Misc); - n[2]: copy n[1] => _8 @ bb2[8]: fn simple1; _8 = _1; - n[3]: copy n[2] => _7 @ bb2[9]: fn simple1; _7 = move _8 as *mut libc::c_void (Misc); - n[4]: free n[3] => _6 @ bb3[2]: fn simple1; _6 = realloc(move _7, move _9); - n[5]: copy n[1] => _16 @ bb4[21]: fn simple1; _16 = _1; - n[6]: ptr_to_int n[5] => _ @ bb4[22]: fn simple1; _15 = move _16 as usize (PointerExposeAddress); + n[0]: alloc _ => _2 @ bb1[2]: fn simple1; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn simple1; _1 = move _2 as *mut pointers::S (Misc); + n[2]: copy n[1] => _8 @ bb2[8]: fn simple1; _8 = _1; + n[3]: copy n[2] => _7 @ bb2[9]: fn simple1; _7 = move _8 as *mut libc::c_void (Misc); + n[4]: free n[3] => _6 @ bb3[2]: fn simple1; _6 = realloc(move _7, move _9); } nodes_that_need_write = [] g { - n[0]: alloc _ => _6 @ bb3[2]: fn simple1; _6 = realloc(move _7, move _9); - n[1]: copy n[0] => _5 @ bb4[2]: fn simple1; _5 = move _6 as *mut pointers::S (Misc); - n[2]: copy n[1] => _11 @ bb4[6]: fn simple1; _11 = _5; - n[3]: field.0 n[2] => _ @ bb4[8]: fn simple1; ((*_11).0: i32) = const 10_i32; - n[4]: addr.store n[3] => _ @ bb4[8]: fn simple1; ((*_11).0: i32) = const 10_i32; - n[5]: copy n[1] => _12 @ bb4[10]: fn simple1; _12 = _5; - n[6]: copy n[2] => _13 @ bb4[13]: fn simple1; _13 = _11; - n[7]: int_to_ptr _ => _17 @ bb4[28]: fn simple1; _17 = move _18 as *const libc::c_void (PointerFromExposedAddress); - n[8]: copy n[1] => _21 @ bb4[34]: fn simple1; _21 = _5; - n[9]: copy n[8] => _20 @ bb4[35]: fn simple1; _20 = move _21 as *mut libc::c_void (Misc); - n[10]: free n[9] => _19 @ bb4[37]: fn simple1; _19 = free(move _20); + n[0]: alloc _ => _6 @ bb3[2]: fn simple1; _6 = realloc(move _7, move _9); + n[1]: copy n[0] => _5 @ bb4[2]: fn simple1; _5 = move _6 as *mut pointers::S (Misc); + n[2]: copy n[1] => _11 @ bb4[6]: fn simple1; _11 = _5; + n[3]: project.0@0 n[2] => _ @ bb4[8]: fn simple1; ((*_11).0: i32) = const 10_i32; + n[4]: addr.store n[2] => _ @ bb4[8]: fn simple1; ((*_11).0: i32) = const 10_i32; + n[5]: copy n[1] => _12 @ bb4[10]: fn simple1; _12 = _5; + n[6]: copy n[2] => _13 @ bb4[13]: fn simple1; _13 = _11; + n[7]: copy n[3] => _16 @ bb4[21]: fn simple1; _16 = _1; + n[8]: ptr_to_int n[7] => _ @ bb4[22]: fn simple1; _15 = move _16 as usize (PointerExposeAddress); + n[9]: int_to_ptr n[3] => _17 @ bb4[28]: fn simple1; _17 = move _18 as *const libc::c_void (PointerFromExposedAddress); + n[10]: copy n[1] => _21 @ bb4[34]: fn simple1; _21 = _5; + n[11]: copy n[10] => _20 @ bb4[35]: fn simple1; _20 = move _21 as *mut libc::c_void (Misc); + n[12]: free n[11] => _19 @ bb4[37]: fn simple1; _19 = free(move _20); } -nodes_that_need_write = [4, 3, 2, 1, 0] +nodes_that_need_write = [4, 2, 1, 0] g { n[0]: &_13 _ => _ @ bb4[14]: fn simple1; _22 = &raw mut _13; @@ -445,15 +442,15 @@ g { n[1]: copy n[0] => _1 @ bb2[1]: fn lighttpd_test; _1 = move _2 as *mut *mut pointers::fdnode_st (Misc); n[2]: copy n[1] => _9 @ bb4[5]: fn lighttpd_test; _9 = _1; n[3]: value.store n[2] => _5.*.0 @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; - n[4]: value.load _ => _8 @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[4]: value.load n[0] => _8 @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); n[5]: offset[0] n[4] => _7 @ bb0[8]: fn fdevent_register; _7 = offset(move _8, move _9); n[6]: copy n[5] => _6 @ bb1[3]: fn fdevent_register; _6 = &mut (*_7); n[7]: addr.store n[6] => _ @ bb2[0]: fn fdevent_register; (*_6) = move _11; n[8]: addr.load n[6] => _ @ bb2[3]: fn fdevent_register; _12 = (*_6); - n[9]: value.load _ => _5 @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[9]: value.load n[5] => _5 @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); n[10]: offset[0] n[9] => _4 @ bb0[9]: fn fdevent_unregister; _4 = offset(move _5, move _6); n[11]: addr.load n[10] => _ @ bb1[2]: fn fdevent_unregister; _3 = (*_4); - n[12]: value.load _ => _19 @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[12]: value.load n[10] => _19 @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); n[13]: offset[0] n[12] => _18 @ bb7[10]: fn fdevent_unregister; _18 = offset(move _19, move _20); n[14]: copy n[13] => _17 @ bb8[3]: fn fdevent_unregister; _17 = &mut (*_18); n[15]: addr.store n[14] => _ @ bb8[4]: fn fdevent_unregister; (*_17) = const 0_usize as *mut pointers::fdnode_st (PointerFromExposedAddress); @@ -461,119 +458,119 @@ g { n[17]: copy n[16] => _19 @ bb6[7]: fn lighttpd_test; _19 = move _20 as *mut libc::c_void (Misc); n[18]: free n[17] => _18 @ bb6[9]: fn lighttpd_test; _18 = free(move _19); } -nodes_that_need_write = [15, 14, 13, 12, 7, 6, 5, 4] - -g { - n[0]: alloc _ => _6 @ bb3[2]: fn lighttpd_test; _6 = malloc(move _7); - n[1]: copy n[0] => _5 @ bb4[1]: fn lighttpd_test; _5 = move _6 as *mut pointers::fdevents (Misc); - n[2]: field.0 n[1] => _ @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; - n[3]: addr.store n[2] => _ @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; - n[4]: copy n[1] => _12 @ bb4[10]: fn lighttpd_test; _12 = _5; - n[5]: value.load _ => _10 @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); - n[6]: copy n[5] => _1 @ bb0[0]: fn fdevent_register; _9 = fdevent_register(move _10, move _11, move _12, move _14); - n[7]: field.0 n[6] => _8 @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[8]: addr.load n[7] => _ @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[9]: value.load _ => _4 @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); - n[10]: copy n[9] => _1 @ bb0[0]: fn fdevent_fdnode_event_del; _3 = fdevent_fdnode_event_del(move _4, move _5); - n[11]: copy n[10] => _7 @ bb2[2]: fn fdevent_fdnode_event_del; _7 = _1; - n[12]: copy n[11] => _1 @ bb0[0]: fn fdevent_fdnode_event_unsetter; _6 = fdevent_fdnode_event_unsetter(move _7, move _8); - n[13]: value.load _ => _7 @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); - n[14]: copy n[13] => _1 @ bb0[0]: fn fdevent_unregister; _6 = fdevent_unregister(move _7, move _8); - n[15]: field.0 n[14] => _5 @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[16]: addr.load n[15] => _ @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[17]: field.0 n[14] => _19 @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[18]: addr.load n[17] => _ @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); - n[19]: copy n[15] => _23 @ bb7[5]: fn lighttpd_test; _23 = _5; - n[20]: copy n[19] => _22 @ bb7[6]: fn lighttpd_test; _22 = move _23 as *mut libc::c_void (Misc); - n[21]: free n[20] => _21 @ bb7[8]: fn lighttpd_test; _21 = free(move _22); +nodes_that_need_write = [15, 14, 13, 12, 10, 9, 7, 6, 5, 4, 0] + +g { + n[0]: alloc _ => _6 @ bb3[2]: fn lighttpd_test; _6 = malloc(move _7); + n[1]: copy n[0] => _5 @ bb4[1]: fn lighttpd_test; _5 = move _6 as *mut pointers::fdevents (Misc); + n[2]: project.0@0 n[1] => _ @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; + n[3]: addr.store n[1] => _ @ bb4[6]: fn lighttpd_test; ((*_5).0: *mut *mut pointers::fdnode_st) = move _9; + n[4]: copy n[1] => _12 @ bb4[10]: fn lighttpd_test; _12 = _5; + n[5]: value.load n[2] => _10 @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); + n[6]: copy n[5] => _1 @ bb0[0]: fn fdevent_register; _9 = fdevent_register(move _10, move _11, move _12, move _14); + n[7]: project.0@0 n[6] => _ @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[8]: addr.load n[6] => _ @ bb0[2]: fn fdevent_register; _8 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[9]: value.load n[7] => _4 @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); + n[10]: copy n[9] => _1 @ bb0[0]: fn fdevent_fdnode_event_del; _3 = fdevent_fdnode_event_del(move _4, move _5); + n[11]: copy n[10] => _7 @ bb2[2]: fn fdevent_fdnode_event_del; _7 = _1; + n[12]: copy n[11] => _1 @ bb0[0]: fn fdevent_fdnode_event_unsetter; _6 = fdevent_fdnode_event_unsetter(move _7, move _8); + n[13]: value.load n[7] => _7 @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); + n[14]: copy n[13] => _1 @ bb0[0]: fn fdevent_unregister; _6 = fdevent_unregister(move _7, move _8); + n[15]: project.0@0 n[14] => _ @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[16]: addr.load n[14] => _ @ bb0[3]: fn fdevent_unregister; _5 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[17]: project.0@0 n[14] => _ @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[18]: addr.load n[14] => _ @ bb7[4]: fn fdevent_unregister; _19 = ((*_1).0: *mut *mut pointers::fdnode_st); + n[19]: copy n[1] => _23 @ bb7[5]: fn lighttpd_test; _23 = _5; + n[20]: copy n[19] => _22 @ bb7[6]: fn lighttpd_test; _22 = move _23 as *mut libc::c_void (Misc); + n[21]: free n[20] => _21 @ bb7[8]: fn lighttpd_test; _21 = free(move _22); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: &_11 _ => _ @ bb4[12]: fn lighttpd_test; _24 = &raw mut _11; - n[1]: addr.store n[0] => _ @ bb4[11]: fn lighttpd_test; _11 = pointers::server { ev: move _12 }; - n[2]: copy n[0] => _10 @ bb4[15]: fn lighttpd_test; _10 = &mut (*_24); - n[3]: copy n[2] => _14 @ bb4[18]: fn lighttpd_test; _14 = &raw mut (*_10); - n[4]: copy n[3] => _1 @ bb0[0]: fn connection_accepted; _13 = connection_accepted(move _14, const 0_i32); - n[5]: field.0 n[4] => _10 @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); - n[6]: addr.load n[5] => _ @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); - n[7]: copy n[5] => _16 @ bb5[4]: fn lighttpd_test; _16 = &raw mut (*_10); - n[8]: copy n[7] => _1 @ bb0[0]: fn connection_close; _15 = connection_close(move _16, move _17); - n[9]: field.0 n[8] => _4 @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); - n[10]: addr.load n[9] => _ @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); - n[11]: field.0 n[8] => _7 @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); - n[12]: addr.load n[11] => _ @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); + n[0]: &_11 _ => _ @ bb4[12]: fn lighttpd_test; _24 = &raw mut _11; + n[1]: addr.store n[0] => _ @ bb4[11]: fn lighttpd_test; _11 = pointers::server { ev: move _12 }; + n[2]: copy n[0] => _10 @ bb4[15]: fn lighttpd_test; _10 = &mut (*_24); + n[3]: copy n[2] => _14 @ bb4[18]: fn lighttpd_test; _14 = &raw mut (*_10); + n[4]: copy n[3] => _1 @ bb0[0]: fn connection_accepted; _13 = connection_accepted(move _14, const 0_i32); + n[5]: project.0@0 n[4] => _ @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); + n[6]: addr.load n[4] => _ @ bb2[10]: fn connection_accepted; _10 = ((*_1).0: *mut pointers::fdevents); + n[7]: copy n[2] => _16 @ bb5[4]: fn lighttpd_test; _16 = &raw mut (*_10); + n[8]: copy n[7] => _1 @ bb0[0]: fn connection_close; _15 = connection_close(move _16, move _17); + n[9]: project.0@0 n[8] => _ @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); + n[10]: addr.load n[8] => _ @ bb0[2]: fn connection_close; _4 = ((*_1).0: *mut pointers::fdevents); + n[11]: project.0@0 n[8] => _ @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); + n[12]: addr.load n[8] => _ @ bb1[5]: fn connection_close; _7 = ((*_1).0: *mut pointers::fdevents); } nodes_that_need_write = [1, 0] g { n[0]: alloc _ => _5 @ bb1[2]: fn connection_accepted; _5 = malloc(move _6); n[1]: copy n[0] => _4 @ bb2[1]: fn connection_accepted; _4 = move _5 as *mut pointers::connection (Misc); - n[2]: field.0 n[1] => _ @ bb2[6]: fn connection_accepted; ((*_4).0: i32) = move _8; - n[3]: addr.store n[2] => _ @ bb2[6]: fn connection_accepted; ((*_4).0: i32) = move _8; - n[4]: field.0 n[1] => _11 @ bb2[12]: fn connection_accepted; _11 = ((*_4).0: i32); - n[5]: addr.load n[4] => _ @ bb2[12]: fn connection_accepted; _11 = ((*_4).0: i32); + n[2]: project.0@0 n[1] => _ @ bb2[6]: fn connection_accepted; ((*_4).0: i32) = move _8; + n[3]: addr.store n[1] => _ @ bb2[6]: fn connection_accepted; ((*_4).0: i32) = move _8; + n[4]: project.0@0 n[1] => _ @ bb2[12]: fn connection_accepted; _11 = ((*_4).0: i32); + n[5]: addr.load n[1] => _ @ bb2[12]: fn connection_accepted; _11 = ((*_4).0: i32); n[6]: copy n[1] => _15 @ bb2[20]: fn connection_accepted; _15 = _4; n[7]: copy n[6] => _14 @ bb2[21]: fn connection_accepted; _14 = move _15 as *mut libc::c_void (Misc); n[8]: copy n[7] => _4 @ bb0[0]: fn fdevent_register; _9 = fdevent_register(move _10, move _11, move _12, move _14); n[9]: copy n[8] => _15 @ bb2[15]: fn fdevent_register; _15 = _4; n[10]: value.store n[9] => _12.*.1 @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; - n[11]: field.1 n[1] => _ @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; - n[12]: addr.store n[11] => _ @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; + n[11]: project.1@8 n[8] => _ @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; + n[12]: addr.store n[8] => _ @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; n[13]: copy n[8] => _0 @ bb3[6]: fn connection_accepted; _0 = _4; n[14]: copy n[13] => _13 @ bb4[19]: fn lighttpd_test; _13 = connection_accepted(move _14, const 0_i32); n[15]: copy n[14] => _17 @ bb5[6]: fn lighttpd_test; _17 = _13; n[16]: copy n[15] => _2 @ bb0[0]: fn connection_close; _15 = connection_close(move _16, move _17); - n[17]: field.1 n[16] => _5 @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); - n[18]: addr.load n[17] => _ @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); - n[19]: field.0 n[16] => _8 @ bb1[7]: fn connection_close; _8 = ((*_2).0: i32); - n[20]: addr.load n[19] => _ @ bb1[7]: fn connection_close; _8 = ((*_2).0: i32); + n[17]: project.1@8 n[16] => _ @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); + n[18]: addr.load n[16] => _ @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); + n[19]: project.0@0 n[16] => _ @ bb1[7]: fn connection_close; _8 = ((*_2).0: i32); + n[20]: addr.load n[16] => _ @ bb1[7]: fn connection_close; _8 = ((*_2).0: i32); n[21]: copy n[16] => _11 @ bb2[6]: fn connection_close; _11 = _2; n[22]: copy n[21] => _10 @ bb2[7]: fn connection_close; _10 = move _11 as *mut libc::c_void (Misc); n[23]: free n[22] => _9 @ bb2[9]: fn connection_close; _9 = free(move _10); } -nodes_that_need_write = [12, 11, 3, 2, 1, 0] - -g { - n[0]: alloc _ => _3 @ bb1[2]: fn fdnode_init; _3 = calloc(move _4, move _6); - n[1]: copy n[0] => _2 @ bb2[2]: fn fdnode_init; _2 = move _3 as *mut pointers::fdnode_st (Misc); - n[2]: copy n[1] => _10 @ bb2[9]: fn fdnode_init; _10 = _2; - n[3]: copy n[2] => _1 @ bb0[0]: fn is_null; _9 = is_null(move _10); - n[4]: copy n[1] => _0 @ bb9[2]: fn fdnode_init; _0 = _2; - n[5]: copy n[4] => _11 @ bb1[5]: fn fdevent_register; _11 = fdnode_init(); - n[6]: value.store n[5] => _6.* @ bb2[0]: fn fdevent_register; (*_6) = move _11; - n[7]: value.load _ => _12 @ bb2[3]: fn fdevent_register; _12 = (*_6); - n[8]: field.0 n[7] => _ @ bb2[8]: fn fdevent_register; ((*_12).0: std::option::Option u32>) = move _13; - n[9]: addr.store n[8] => _ @ bb2[8]: fn fdevent_register; ((*_12).0: std::option::Option u32>) = move _13; - n[10]: field.2 n[7] => _ @ bb2[12]: fn fdevent_register; ((*_12).2: i32) = move _14; - n[11]: addr.store n[10] => _ @ bb2[12]: fn fdevent_register; ((*_12).2: i32) = move _14; - n[12]: field.1 n[7] => _ @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; - n[13]: addr.store n[12] => _ @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; - n[14]: field.3 n[7] => _ @ bb2[20]: fn fdevent_register; ((*_12).3: i32) = move _16; - n[15]: addr.store n[14] => _ @ bb2[20]: fn fdevent_register; ((*_12).3: i32) = move _16; - n[16]: field.4 n[7] => _ @ bb2[24]: fn fdevent_register; ((*_12).4: i32) = Neg(move _17); - n[17]: addr.store n[16] => _ @ bb2[24]: fn fdevent_register; ((*_12).4: i32) = Neg(move _17); - n[18]: copy n[7] => _0 @ bb2[26]: fn fdevent_register; _0 = _12; - n[19]: copy n[18] => _9 @ bb2[23]: fn connection_accepted; _9 = fdevent_register(move _10, move _11, move _12, move _14); - n[20]: value.store n[19] => _4.*.1 @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; - n[21]: value.load _ => _5 @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); - n[22]: copy n[21] => _2 @ bb0[0]: fn fdevent_fdnode_event_del; _3 = fdevent_fdnode_event_del(move _4, move _5); - n[23]: copy n[22] => _5 @ bb0[3]: fn fdevent_fdnode_event_del; _5 = _2; - n[24]: copy n[23] => _1 @ bb0[0]: fn is_null; _4 = is_null(move _5); - n[25]: copy n[22] => _8 @ bb2[4]: fn fdevent_fdnode_event_del; _8 = _2; - n[26]: copy n[25] => _2 @ bb0[0]: fn fdevent_fdnode_event_unsetter; _6 = fdevent_fdnode_event_unsetter(move _7, move _8); - n[27]: field.4 n[26] => _7 @ bb0[8]: fn fdevent_fdnode_event_unsetter; _7 = ((*_2).4: i32); - n[28]: addr.load n[27] => _ @ bb0[8]: fn fdevent_fdnode_event_unsetter; _7 = ((*_2).4: i32); - n[29]: value.load _ => _3 @ bb1[2]: fn fdevent_unregister; _3 = (*_4); - n[30]: copy n[29] => _12 @ bb1[11]: fn fdevent_unregister; _12 = _3; - n[31]: ptr_to_int n[30] => _ @ bb1[12]: fn fdevent_unregister; _11 = move _12 as usize (PointerExposeAddress); - n[32]: copy n[29] => _23 @ bb8[7]: fn fdevent_unregister; _23 = _3; - n[33]: copy n[32] => _1 @ bb0[0]: fn fdnode_free; _22 = fdnode_free(move _23); - n[34]: copy n[33] => _4 @ bb0[3]: fn fdnode_free; _4 = _1; - n[35]: copy n[34] => _3 @ bb0[4]: fn fdnode_free; _3 = move _4 as *mut libc::c_void (Misc); - n[36]: free n[35] => _2 @ bb0[6]: fn fdnode_free; _2 = free(move _3); -} -nodes_that_need_write = [17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7] +nodes_that_need_write = [12, 8, 7, 6, 3, 1, 0] + +g { + n[0]: alloc _ => _3 @ bb1[2]: fn fdnode_init; _3 = calloc(move _4, move _6); + n[1]: copy n[0] => _2 @ bb2[2]: fn fdnode_init; _2 = move _3 as *mut pointers::fdnode_st (Misc); + n[2]: copy n[1] => _10 @ bb2[9]: fn fdnode_init; _10 = _2; + n[3]: copy n[2] => _1 @ bb0[0]: fn is_null; _9 = is_null(move _10); + n[4]: copy n[1] => _0 @ bb9[2]: fn fdnode_init; _0 = _2; + n[5]: copy n[4] => _11 @ bb1[5]: fn fdevent_register; _11 = fdnode_init(); + n[6]: value.store n[5] => _6.* @ bb2[0]: fn fdevent_register; (*_6) = move _11; + n[7]: value.load n[0] => _12 @ bb2[3]: fn fdevent_register; _12 = (*_6); + n[8]: project.0@0 n[7] => _ @ bb2[8]: fn fdevent_register; ((*_12).0: std::option::Option u32>) = move _13; + n[9]: addr.store n[7] => _ @ bb2[8]: fn fdevent_register; ((*_12).0: std::option::Option u32>) = move _13; + n[10]: project.2@16 n[7] => _ @ bb2[12]: fn fdevent_register; ((*_12).2: i32) = move _14; + n[11]: addr.store n[7] => _ @ bb2[12]: fn fdevent_register; ((*_12).2: i32) = move _14; + n[12]: project.1@8 n[7] => _ @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; + n[13]: addr.store n[7] => _ @ bb2[16]: fn fdevent_register; ((*_12).1: *mut libc::c_void) = move _15; + n[14]: project.3@20 n[7] => _ @ bb2[20]: fn fdevent_register; ((*_12).3: i32) = move _16; + n[15]: addr.store n[7] => _ @ bb2[20]: fn fdevent_register; ((*_12).3: i32) = move _16; + n[16]: project.4@24 n[7] => _ @ bb2[24]: fn fdevent_register; ((*_12).4: i32) = Neg(move _17); + n[17]: addr.store n[7] => _ @ bb2[24]: fn fdevent_register; ((*_12).4: i32) = Neg(move _17); + n[18]: copy n[7] => _0 @ bb2[26]: fn fdevent_register; _0 = _12; + n[19]: copy n[18] => _9 @ bb2[23]: fn connection_accepted; _9 = fdevent_register(move _10, move _11, move _12, move _14); + n[20]: value.store n[19] => _4.*.1 @ bb3[4]: fn connection_accepted; ((*_4).1: *mut pointers::fdnode_st) = move _9; + n[21]: value.load n[8] => _5 @ bb0[4]: fn connection_close; _5 = ((*_2).1: *mut pointers::fdnode_st); + n[22]: copy n[21] => _2 @ bb0[0]: fn fdevent_fdnode_event_del; _3 = fdevent_fdnode_event_del(move _4, move _5); + n[23]: copy n[22] => _5 @ bb0[3]: fn fdevent_fdnode_event_del; _5 = _2; + n[24]: copy n[23] => _1 @ bb0[0]: fn is_null; _4 = is_null(move _5); + n[25]: copy n[22] => _8 @ bb2[4]: fn fdevent_fdnode_event_del; _8 = _2; + n[26]: copy n[25] => _2 @ bb0[0]: fn fdevent_fdnode_event_unsetter; _6 = fdevent_fdnode_event_unsetter(move _7, move _8); + n[27]: project.4@24 n[26] => _ @ bb0[8]: fn fdevent_fdnode_event_unsetter; _7 = ((*_2).4: i32); + n[28]: addr.load n[26] => _ @ bb0[8]: fn fdevent_fdnode_event_unsetter; _7 = ((*_2).4: i32); + n[29]: value.load n[8] => _3 @ bb1[2]: fn fdevent_unregister; _3 = (*_4); + n[30]: copy n[29] => _12 @ bb1[11]: fn fdevent_unregister; _12 = _3; + n[31]: ptr_to_int n[30] => _ @ bb1[12]: fn fdevent_unregister; _11 = move _12 as usize (PointerExposeAddress); + n[32]: copy n[29] => _23 @ bb8[7]: fn fdevent_unregister; _23 = _3; + n[33]: copy n[32] => _1 @ bb0[0]: fn fdnode_free; _22 = fdnode_free(move _23); + n[34]: copy n[33] => _4 @ bb0[3]: fn fdnode_free; _4 = _1; + n[35]: copy n[34] => _3 @ bb0[4]: fn fdnode_free; _3 = move _4 as *mut libc::c_void (Misc); + n[36]: free n[35] => _2 @ bb0[6]: fn fdnode_free; _2 = free(move _3); +} +nodes_that_need_write = [17, 15, 13, 11, 9, 7, 0] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_malloc_free; _1 = malloc(move _2); @@ -717,73 +714,71 @@ g { nodes_that_need_write = [] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_store_addr; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn test_store_addr; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb2[4]: fn test_store_addr; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb2[4]: fn test_store_addr; ((*_1).0: i32) = const 10_i32; - n[4]: copy n[1] => _7 @ bb2[8]: fn test_store_addr; _7 = _1; - n[5]: copy n[4] => _6 @ bb2[9]: fn test_store_addr; _6 = move _7 as *mut libc::c_void (Misc); - n[6]: free n[5] => _5 @ bb2[11]: fn test_store_addr; _5 = free(move _6); + n[0]: alloc _ => _2 @ bb1[2]: fn test_store_addr; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn test_store_addr; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[4]: fn test_store_addr; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb2[4]: fn test_store_addr; ((*_1).0: i32) = const 10_i32; + n[4]: copy n[1] => _7 @ bb2[8]: fn test_store_addr; _7 = _1; + n[5]: copy n[4] => _6 @ bb2[9]: fn test_store_addr; _6 = move _7 as *mut libc::c_void (Misc); + n[6]: free n[5] => _5 @ bb2[11]: fn test_store_addr; _5 = free(move _6); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_load_other_store_self; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn test_load_other_store_self; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb4[4]: fn test_load_other_store_self; ((*_1).0: i32) = const 10_i32; - n[3]: addr.store n[2] => _ @ bb4[4]: fn test_load_other_store_self; ((*_1).0: i32) = const 10_i32; - n[4]: field.0 n[1] => _9 @ bb4[6]: fn test_load_other_store_self; _9 = ((*_1).0: i32); - n[5]: addr.load n[4] => _ @ bb4[6]: fn test_load_other_store_self; _9 = ((*_1).0: i32); - n[6]: copy n[1] => _12 @ bb4[12]: fn test_load_other_store_self; _12 = _1; - n[7]: copy n[6] => _11 @ bb4[13]: fn test_load_other_store_self; _11 = move _12 as *mut libc::c_void (Misc); - n[8]: free n[7] => _10 @ bb4[15]: fn test_load_other_store_self; _10 = free(move _11); + n[0]: alloc _ => _2 @ bb1[2]: fn test_load_other_store_self; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn test_load_other_store_self; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb4[4]: fn test_load_other_store_self; ((*_1).0: i32) = const 10_i32; + n[3]: addr.store n[1] => _ @ bb4[4]: fn test_load_other_store_self; ((*_1).0: i32) = const 10_i32; + n[4]: project.0@0 n[1] => _ @ bb4[6]: fn test_load_other_store_self; _9 = ((*_1).0: i32); + n[5]: addr.load n[1] => _ @ bb4[6]: fn test_load_other_store_self; _9 = ((*_1).0: i32); + n[6]: copy n[1] => _12 @ bb4[12]: fn test_load_other_store_self; _12 = _1; + n[7]: copy n[6] => _11 @ bb4[13]: fn test_load_other_store_self; _11 = move _12 as *mut libc::c_void (Misc); + n[8]: free n[7] => _10 @ bb4[15]: fn test_load_other_store_self; _10 = free(move _11); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _6 @ bb3[2]: fn test_load_other_store_self; _6 = malloc(move _7); - n[1]: copy n[0] => _5 @ bb4[1]: fn test_load_other_store_self; _5 = move _6 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _ @ bb4[7]: fn test_load_other_store_self; ((*_5).0: i32) = move _9; - n[3]: addr.store n[2] => _ @ bb4[7]: fn test_load_other_store_self; ((*_5).0: i32) = move _9; - n[4]: copy n[1] => _15 @ bb5[5]: fn test_load_other_store_self; _15 = _5; - n[5]: copy n[4] => _14 @ bb5[6]: fn test_load_other_store_self; _14 = move _15 as *mut libc::c_void (Misc); - n[6]: free n[5] => _13 @ bb5[8]: fn test_load_other_store_self; _13 = free(move _14); + n[0]: alloc _ => _6 @ bb3[2]: fn test_load_other_store_self; _6 = malloc(move _7); + n[1]: copy n[0] => _5 @ bb4[1]: fn test_load_other_store_self; _5 = move _6 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb4[7]: fn test_load_other_store_self; ((*_5).0: i32) = move _9; + n[3]: addr.store n[1] => _ @ bb4[7]: fn test_load_other_store_self; ((*_5).0: i32) = move _9; + n[4]: copy n[1] => _15 @ bb5[5]: fn test_load_other_store_self; _15 = _5; + n[5]: copy n[4] => _14 @ bb5[6]: fn test_load_other_store_self; _14 = move _15 as *mut libc::c_void (Misc); + n[6]: free n[5] => _13 @ bb5[8]: fn test_load_other_store_self; _13 = free(move _14); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_load_self_store_self; _2 = calloc(move _3, move _4); - n[1]: copy n[0] => _1 @ bb2[2]: fn test_load_self_store_self; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.3 n[1] => _ @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); - n[3]: field.3 n[2] => _6 @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); - n[4]: addr.load n[3] => _ @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); - n[5]: field.3 n[1] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; - n[6]: field.3 n[5] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; - n[7]: addr.store n[6] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; - n[8]: copy n[1] => _9 @ bb2[12]: fn test_load_self_store_self; _9 = _1; - n[9]: copy n[8] => _8 @ bb2[13]: fn test_load_self_store_self; _8 = move _9 as *mut libc::c_void (Misc); - n[10]: free n[9] => _7 @ bb2[15]: fn test_load_self_store_self; _7 = free(move _8); + n[0]: alloc _ => _2 @ bb1[2]: fn test_load_self_store_self; _2 = calloc(move _3, move _4); + n[1]: copy n[0] => _1 @ bb2[2]: fn test_load_self_store_self; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.5@48 n[1] => _ @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); + n[3]: addr.load n[1] => _ @ bb2[6]: fn test_load_self_store_self; _6 = (((*_1).3: pointers::T).3: i32); + n[4]: project.5@48 n[1] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; + n[5]: addr.store n[1] => _ @ bb2[7]: fn test_load_self_store_self; (((*_1).3: pointers::T).3: i32) = move _6; + n[6]: copy n[1] => _9 @ bb2[12]: fn test_load_self_store_self; _9 = _1; + n[7]: copy n[6] => _8 @ bb2[13]: fn test_load_self_store_self; _8 = move _9 as *mut libc::c_void (Misc); + n[8]: free n[7] => _7 @ bb2[15]: fn test_load_self_store_self; _7 = free(move _8); } -nodes_that_need_write = [7, 6, 5, 1, 0] +nodes_that_need_write = [5, 1, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_load_self_store_self_inter; _2 = calloc(move _3, move _4); - n[1]: copy n[0] => _1 @ bb2[2]: fn test_load_self_store_self_inter; _1 = move _2 as *mut pointers::S (Misc); - n[2]: field.0 n[1] => _6 @ bb2[6]: fn test_load_self_store_self_inter; _6 = ((*_1).0: i32); - n[3]: addr.load n[2] => _ @ bb2[6]: fn test_load_self_store_self_inter; _6 = ((*_1).0: i32); - n[4]: field.0 n[1] => _ @ bb2[10]: fn test_load_self_store_self_inter; ((*_1).0: i32) = move _7; - n[5]: addr.store n[4] => _ @ bb2[10]: fn test_load_self_store_self_inter; ((*_1).0: i32) = move _7; - n[6]: copy n[1] => _10 @ bb2[15]: fn test_load_self_store_self_inter; _10 = _1; - n[7]: copy n[6] => _9 @ bb2[16]: fn test_load_self_store_self_inter; _9 = move _10 as *mut libc::c_void (Misc); - n[8]: free n[7] => _8 @ bb2[18]: fn test_load_self_store_self_inter; _8 = free(move _9); + n[0]: alloc _ => _2 @ bb1[2]: fn test_load_self_store_self_inter; _2 = calloc(move _3, move _4); + n[1]: copy n[0] => _1 @ bb2[2]: fn test_load_self_store_self_inter; _1 = move _2 as *mut pointers::S (Misc); + n[2]: project.0@0 n[1] => _ @ bb2[6]: fn test_load_self_store_self_inter; _6 = ((*_1).0: i32); + n[3]: addr.load n[1] => _ @ bb2[6]: fn test_load_self_store_self_inter; _6 = ((*_1).0: i32); + n[4]: project.0@0 n[1] => _ @ bb2[10]: fn test_load_self_store_self_inter; ((*_1).0: i32) = move _7; + n[5]: addr.store n[1] => _ @ bb2[10]: fn test_load_self_store_self_inter; ((*_1).0: i32) = move _7; + n[6]: copy n[1] => _10 @ bb2[15]: fn test_load_self_store_self_inter; _10 = _1; + n[7]: copy n[6] => _9 @ bb2[16]: fn test_load_self_store_self_inter; _9 = move _10 as *mut libc::c_void (Misc); + n[8]: free n[7] => _8 @ bb2[18]: fn test_load_self_store_self_inter; _8 = free(move _9); } -nodes_that_need_write = [5, 4, 1, 0] +nodes_that_need_write = [5, 1, 0] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_ptr_int_ptr; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_ptr_int_ptr; _5 = _1; n[2]: ptr_to_int n[1] => _ @ bb2[5]: fn test_ptr_int_ptr; _4 = move _5 as usize (PointerExposeAddress); - n[3]: int_to_ptr _ => _1 @ bb2[10]: fn test_ptr_int_ptr; _1 = move _6 as *mut libc::c_void (PointerFromExposedAddress); + n[3]: int_to_ptr n[0] => _1 @ bb2[10]: fn test_ptr_int_ptr; _1 = move _6 as *mut libc::c_void (PointerFromExposedAddress); n[4]: copy n[3] => _8 @ bb2[14]: fn test_ptr_int_ptr; _8 = _1; n[5]: free n[4] => _7 @ bb2[15]: fn test_ptr_int_ptr; _7 = free(move _8); } @@ -791,7 +786,7 @@ nodes_that_need_write = [] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_load_value; _1 = malloc(move _2); - n[1]: value.load _ => _6 @ bb2[8]: fn test_load_value; _6 = (*_4); + n[1]: value.load n[0] => _6 @ bb2[8]: fn test_load_value; _6 = (*_4); n[2]: free n[1] => _5 @ bb2[9]: fn test_load_value; _5 = free(move _6); } nodes_that_need_write = [] @@ -805,10 +800,10 @@ nodes_that_need_write = [] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_store_value; _1 = malloc(move _2); - n[1]: value.load _ => _4 @ bb2[4]: fn test_store_value; _4 = (*_9); + n[1]: value.load n[0] => _4 @ bb2[4]: fn test_store_value; _4 = (*_9); n[2]: copy n[1] => _6 @ bb2[10]: fn test_store_value; _6 = _4; n[3]: value.store n[2] => _5.* @ bb2[11]: fn test_store_value; (*_5) = move _6; - n[4]: value.load _ => _8 @ bb2[15]: fn test_store_value; _8 = (*_9); + n[4]: value.load n[0] => _8 @ bb2[15]: fn test_store_value; _8 = (*_9); n[5]: free n[4] => _7 @ bb2[16]: fn test_store_value; _7 = free(move _8); } nodes_that_need_write = [] @@ -823,38 +818,38 @@ g { nodes_that_need_write = [3, 2, 0] g { - n[0]: alloc _ => _2 @ bb1[2]: fn test_store_value_field; _2 = malloc(move _3); - n[1]: copy n[0] => _1 @ bb2[1]: fn test_store_value_field; _1 = move _2 as *mut pointers::S (Misc); - n[2]: copy n[1] => _9 @ bb4[5]: fn test_store_value_field; _9 = _1; - n[3]: value.store n[2] => _5.*.2 @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); - n[4]: value.load _ => _10 @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); - n[5]: field.2 n[1] => _ @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; - n[6]: addr.store n[5] => _ @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; - n[7]: value.store n[4] => _1.*.2 @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; - n[8]: copy n[1] => _16 @ bb5[5]: fn test_store_value_field; _16 = _1; - n[9]: copy n[8] => _15 @ bb5[6]: fn test_store_value_field; _15 = move _16 as *mut libc::c_void (Misc); - n[10]: free n[9] => _14 @ bb5[8]: fn test_store_value_field; _14 = free(move _15); + n[0]: alloc _ => _2 @ bb1[2]: fn test_store_value_field; _2 = malloc(move _3); + n[1]: copy n[0] => _1 @ bb2[1]: fn test_store_value_field; _1 = move _2 as *mut pointers::S (Misc); + n[2]: copy n[1] => _9 @ bb4[5]: fn test_store_value_field; _9 = _1; + n[3]: value.store n[2] => _5.*.2 @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); + n[4]: value.load n[0] => _10 @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); + n[5]: project.2@16 n[1] => _ @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; + n[6]: addr.store n[1] => _ @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; + n[7]: value.store n[4] => _1.*.2 @ bb4[10]: fn test_store_value_field; ((*_1).2: *const pointers::S) = move _10; + n[8]: copy n[1] => _16 @ bb5[5]: fn test_store_value_field; _16 = _1; + n[9]: copy n[8] => _15 @ bb5[6]: fn test_store_value_field; _15 = move _16 as *mut libc::c_void (Misc); + n[10]: free n[9] => _14 @ bb5[8]: fn test_store_value_field; _14 = free(move _15); } -nodes_that_need_write = [6, 5, 1, 0] +nodes_that_need_write = [6, 1, 0] g { - n[0]: alloc _ => _6 @ bb3[2]: fn test_store_value_field; _6 = malloc(move _7); - n[1]: copy n[0] => _5 @ bb4[1]: fn test_store_value_field; _5 = move _6 as *mut pointers::S (Misc); - n[2]: field.2 n[1] => _ @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); - n[3]: addr.store n[2] => _ @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); - n[4]: field.2 n[1] => _10 @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); - n[5]: addr.load n[4] => _ @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); - n[6]: copy n[1] => _13 @ bb4[15]: fn test_store_value_field; _13 = _5; - n[7]: copy n[6] => _12 @ bb4[16]: fn test_store_value_field; _12 = move _13 as *mut libc::c_void (Misc); - n[8]: free n[7] => _11 @ bb4[18]: fn test_store_value_field; _11 = free(move _12); + n[0]: alloc _ => _6 @ bb3[2]: fn test_store_value_field; _6 = malloc(move _7); + n[1]: copy n[0] => _5 @ bb4[1]: fn test_store_value_field; _5 = move _6 as *mut pointers::S (Misc); + n[2]: project.2@16 n[1] => _ @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); + n[3]: addr.store n[1] => _ @ bb4[6]: fn test_store_value_field; ((*_5).2: *const pointers::S) = move _9 as *const pointers::S (Pointer(MutToConstPointer)); + n[4]: project.2@16 n[1] => _ @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); + n[5]: addr.load n[1] => _ @ bb4[9]: fn test_store_value_field; _10 = ((*_5).2: *const pointers::S); + n[6]: copy n[1] => _13 @ bb4[15]: fn test_store_value_field; _13 = _5; + n[7]: copy n[6] => _12 @ bb4[16]: fn test_store_value_field; _12 = move _13 as *mut libc::c_void (Misc); + n[8]: free n[7] => _11 @ bb4[18]: fn test_store_value_field; _11 = free(move _12); } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [3, 1, 0] g { n[0]: alloc _ => _1 @ bb1[2]: fn test_load_value_store_value; _1 = malloc(move _2); - n[1]: value.load _ => _5 @ bb2[7]: fn test_load_value_store_value; _5 = (*_4); + n[1]: value.load n[0] => _5 @ bb2[7]: fn test_load_value_store_value; _5 = (*_4); n[2]: value.store n[1] => _4.* @ bb2[8]: fn test_load_value_store_value; (*_4) = move _5; - n[3]: value.load _ => _7 @ bb2[12]: fn test_load_value_store_value; _7 = (*_4); + n[3]: value.load n[0] => _7 @ bb2[12]: fn test_load_value_store_value; _7 = (*_4); n[4]: free n[3] => _6 @ bb2[13]: fn test_load_value_store_value; _6 = free(move _7); } nodes_that_need_write = [] @@ -951,17 +946,15 @@ g { nodes_that_need_write = [77, 76, 75, 68, 67, 66, 65, 64, 63, 56, 55, 54, 47, 46, 45, 35, 34, 33, 29, 28, 27, 17, 16, 15, 8, 7, 6, 2, 1, 0] g { - n[0]: &_4 _ => _ @ bb0[12]: fn test_ref_field; _8 = &raw mut _4; - n[1]: addr.store n[0] => _ @ bb0[11]: fn test_ref_field; _4 = pointers::S { field: const 0_i32, field2: const 0_u64, field3: move _5, field4: move _6 }; - n[2]: copy n[0] => _3 @ bb0[16]: fn test_ref_field; _3 = &mut (*_8); - n[3]: field.3 n[2] => _ @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); - n[4]: field.3 n[3] => _7 @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); - n[5]: addr.load n[4] => _ @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); - n[6]: field.3 n[2] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; - n[7]: field.3 n[6] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; - n[8]: addr.store n[7] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; + n[0]: &_4 _ => _ @ bb0[12]: fn test_ref_field; _8 = &raw mut _4; + n[1]: addr.store n[0] => _ @ bb0[11]: fn test_ref_field; _4 = pointers::S { field: const 0_i32, field2: const 0_u64, field3: move _5, field4: move _6 }; + n[2]: copy n[0] => _3 @ bb0[16]: fn test_ref_field; _3 = &mut (*_8); + n[3]: project.5@48 n[2] => _ @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); + n[4]: addr.load n[2] => _ @ bb0[18]: fn test_ref_field; _7 = (((*_3).3: pointers::T).3: i32); + n[5]: project.5@48 n[2] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; + n[6]: addr.store n[2] => _ @ bb0[19]: fn test_ref_field; (((*_3).3: pointers::T).3: i32) = move _7; } -nodes_that_need_write = [8, 7, 6, 2, 1, 0] +nodes_that_need_write = [6, 2, 1, 0] g { n[0]: &_1 _ => _ @ bb0[2]: fn test_addr_taken; _8 = &raw mut _1; @@ -973,12 +966,12 @@ g { nodes_that_need_write = [1, 0] g { - n[0]: &_1 _ => _ @ bb0[0]: fn test_addr_taken_arg; _3 = &raw mut _1; - n[1]: field.2 n[0] => _ @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[2]: addr.store n[1] => _ @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); - n[3]: copy n[0] => _2 @ bb0[3]: fn test_addr_taken_arg; _2 = &(*_3); + n[0]: &_1 _ => _ @ bb0[0]: fn test_addr_taken_arg; _3 = &raw mut _1; + n[1]: project.2@16 n[0] => _ @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[2]: addr.store n[0] => _ @ bb0[1]: fn test_addr_taken_arg; ((*_3).2: *const pointers::S) = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[3]: copy n[0] => _2 @ bb0[3]: fn test_addr_taken_arg; _2 = &(*_3); } -nodes_that_need_write = [2, 1, 0] +nodes_that_need_write = [2, 0] g { n[0]: &_3 _ => _ @ bb2[2]: fn test_addr_taken_loop; _19 = &raw mut _3; @@ -1029,6 +1022,6 @@ g { } nodes_that_need_write = [1, 0] -num_graphs = 67 -num_nodes = 759 +num_graphs = 66 +num_nodes = 755