diff --git a/Cargo.lock b/Cargo.lock index 7efd0ec8fe..63d149b437 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -153,7 +153,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.16", + "syn 2.0.75", "which", ] @@ -172,6 +172,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "c2rust" version = "0.19.0" @@ -304,6 +310,7 @@ dependencies = [ "itertools", "log", "once_cell", + "rand", "tempfile", "toml_edit", ] @@ -456,7 +463,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.75", ] [[package]] @@ -741,6 +748,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gimli" version = "0.27.2" @@ -1070,7 +1088,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.75", ] [[package]] @@ -1101,6 +1119,15 @@ dependencies = [ "rustc-hash", ] +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "prettyplease" version = "0.1.25" @@ -1118,7 +1145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617feabb81566b593beb4886fb8c1f38064169dae4dccad0e3220160c3b37203" dependencies = [ "proc-macro2", - "syn 2.0.16", + "syn 2.0.75", ] [[package]] @@ -1156,22 +1183,52 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.57" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.27" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -1282,7 +1339,7 @@ checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.75", ] [[package]] @@ -1372,9 +1429,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.16" +version = "2.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" dependencies = [ "proc-macro2", "quote", @@ -1438,7 +1495,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.16", + "syn 2.0.75", ] [[package]] @@ -1552,6 +1609,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "which" version = "4.4.0" @@ -1758,3 +1821,24 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" dependencies = [ "linked-hash-map", ] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.75", +] diff --git a/analysis/runtime/src/events.rs b/analysis/runtime/src/events.rs index 9338119b39..12d168e409 100644 --- a/analysis/runtime/src/events.rs +++ b/analysis/runtime/src/events.rs @@ -28,12 +28,12 @@ pub enum EventKind { /// the pointer. CopyPtr(Pointer), - 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`. + /// The third value is a "projection key" 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, u64), Alloc { size: usize, @@ -61,8 +61,19 @@ pub enum EventKind { /// are necessary for its underlying address. StoreAddrTaken(Pointer), - /// The pointer that appears as the address result of addr_of(Local) - AddrOfLocal(Pointer, Local), + /// The pointer that appears as the address result of addr_of(Local). + /// The fields encode the pointer of the local, its MIR index, and its size. + AddrOfLocal { + ptr: Pointer, + local: Local, + size: u32, + }, + + /// The address and size of a sized pointee of a pointer. + AddrOfSized { + ptr: Pointer, + size: usize, + }, /// Casting the pointer to an int ToInt(Pointer), @@ -90,7 +101,9 @@ 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, idx) => { + write!(f, "project(0x{:x}, 0x{:x}, [{}])", ptr, new_ptr, idx) + } Alloc { size, ptr } => { write!(f, "malloc({}) -> 0x{:x}", size, ptr) } @@ -106,8 +119,10 @@ impl Debug for EventKind { LoadAddr(ptr) => write!(f, "load(0x{:x})", ptr), StoreAddr(ptr) => write!(f, "store(0x{:x})", ptr), StoreAddrTaken(ptr) => write!(f, "store(0x{:x})", ptr), - CopyRef => write!(f, "copy_ref"), - AddrOfLocal(ptr, _) => write!(f, "addr_of_local = 0x{:x}", ptr), + AddrOfLocal { ptr, local, size } => { + write!(f, "addr_of_local({:?}, {}) = 0x{:x}", local, size, ptr) + } + AddrOfSized { ptr, size } => write!(f, "addr_of_sized({}) = 0x{:x}", size, ptr), ToInt(ptr) => write!(f, "to_int(0x{:x})", ptr), FromInt(ptr) => write!(f, "from_int(0x{:x})", ptr), LoadValue(ptr) => write!(f, "load_value(0x{:x})", ptr), diff --git a/analysis/runtime/src/handlers.rs b/analysis/runtime/src/handlers.rs index 03b2075f66..fae5f24079 100644 --- a/analysis/runtime/src/handlers.rs +++ b/analysis/runtime/src/handlers.rs @@ -82,6 +82,18 @@ pub fn reallocarray(mir_loc: MirLocId, old_ptr: usize, nmemb: u64, size: u64, ne /// = note: rustdoc does not allow disambiguating between `*const` and `*mut`, and pointers are unstable until it does /// ``` pub fn offset(mir_loc: MirLocId, ptr: usize, offset: isize, new_ptr: usize) { + // Corner case: Offset(..) events with a base pointer of zero are special + // because the result might be an actual pointer, e.g., c2rust will + // emit a pointer increment `a += b` as `a = a.offset(b)` which we need + // to ignore here if `a == 0` which is equivalent to `a = b`. + if ptr == 0 { + RUNTIME.send_event(Event { + mir_loc, + kind: EventKind::CopyPtr(offset as usize), + }); + return; + } + RUNTIME.send_event(Event { mir_loc, kind: EventKind::Offset(ptr, offset, new_ptr), @@ -110,10 +122,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, proj_key: u64) { RUNTIME.send_event(Event { mir_loc, - kind: EventKind::Field(ptr, field_id), + kind: EventKind::Project(ptr, new_ptr, proj_key), }); } @@ -138,10 +150,25 @@ pub fn ptr_to_int(mir_loc: MirLocId, ptr: usize) { }); } -pub fn addr_of_local(mir_loc: MirLocId, ptr: usize, local: u32) { +pub fn addr_of_local(mir_loc: MirLocId, ptr: usize, local: u32, size: u32) { RUNTIME.send_event(Event { mir_loc, - kind: EventKind::AddrOfLocal(ptr, local.into()), + kind: EventKind::AddrOfLocal { + ptr, + local: local.into(), + size, + }, + }); +} + +pub fn addr_of_sized(mir_loc: MirLocId, ptr: *const T) { + let size = unsafe { core::mem::size_of_val(&*ptr) }; + RUNTIME.send_event(Event { + mir_loc, + kind: EventKind::AddrOfSized { + ptr: ptr as *const u8 as usize, + size, + }, }); } diff --git a/analysis/runtime/src/metadata.rs b/analysis/runtime/src/metadata.rs index 0856bf8d6e..a37d1b2f96 100644 --- a/analysis/runtime/src/metadata.rs +++ b/analysis/runtime/src/metadata.rs @@ -13,6 +13,7 @@ use crate::mir_loc::{Func, FuncId, MirLoc, MirLocId}; pub struct Metadata { pub locs: Vec, pub functions: HashMap, + pub projections: HashMap>, } impl Metadata { @@ -46,11 +47,27 @@ impl FromIterator for Metadata { fn from_iter>(iter: I) -> Self { let mut locs = Vec::new(); let mut functions = HashMap::new(); + let mut projections = HashMap::new(); for metadata in iter { locs.extend(metadata.locs); functions.extend(metadata.functions); + + for (key, proj) in metadata.projections.into_iter() { + projections + .entry(key) + .and_modify(|old_proj| { + panic!( + "Projection key collision at {key:x} between {old_proj:?} and {proj:?}" + ) + }) + .or_insert(proj); + } + } + Self { + locs, + functions, + projections, } - Self { locs, functions } } } diff --git a/analysis/tests/minimal/reference_pdg.bc b/analysis/tests/minimal/reference_pdg.bc index 6a9034e8d4..c116f49613 100644 Binary files a/analysis/tests/minimal/reference_pdg.bc and b/analysis/tests/minimal/reference_pdg.bc differ diff --git a/analysis/tests/misc/src/pointers.rs b/analysis/tests/misc/src/pointers.rs index 4d165bfff9..e7366fe999 100644 --- a/analysis/tests/misc/src/pointers.rs +++ b/analysis/tests/misc/src/pointers.rs @@ -93,6 +93,9 @@ pub unsafe extern "C" fn malloc_wrapper(mut size: size_t) -> *mut libc::c_void { #[no_mangle] pub unsafe extern "C" fn recur(x: libc::c_int, s: *mut S) { if x == 0 { + if s.is_null() { + return; + } return free(s as *mut libc::c_void); } @@ -122,6 +125,7 @@ pub unsafe extern "C" fn simple() { let s = *y; *x = s; recur(3, x); + recur(3, std::ptr::null_mut()); free(x2 as *mut libc::c_void); } @@ -742,7 +746,11 @@ unsafe fn main_0(mut argc: libc::c_int, mut argv: *mut *mut libc::c_char) -> lib test_load_value_store_value(); let nums = &mut [2i32, 5i32, 3i32, 1i32, 6i32]; insertion_sort(nums.len() as libc::c_int, nums as *mut libc::c_int); - test_ref_field(); + // TODO: this test is broken on Darwin because the fields structure fields + // alias with locals of other functions, and the locals are different between + // Linux and Darwin. We should re-enable test_ref_field once we track stack + // lifetimes (see https://github.com/immunant/c2rust/issues/1117). + //test_ref_field(); test_addr_taken(); let mut t = T { field: 0i32, diff --git a/c2rust-analyze/src/analyze.rs b/c2rust-analyze/src/analyze.rs index ca06002a4c..84391a23a7 100644 --- a/c2rust-analyze/src/analyze.rs +++ b/c2rust-analyze/src/analyze.rs @@ -943,16 +943,40 @@ fn run(tcx: TyCtxt) { let f = std::fs::File::open(pdg_file_path).unwrap(); let graphs: Graphs = bincode::deserialize_from(f).unwrap(); + let mut known_nulls = HashSet::new(); + for g in &graphs.graphs { + for n in &g.nodes { + let dest_pl = match n.dest.as_ref() { + Some(x) => x, + None => { + continue; + } + }; + if !dest_pl.projection.is_empty() { + continue; + } + let dest = dest_pl.local; + let dest = Local::from_u32(dest.index); + if g.is_null { + known_nulls.insert((n.function.id, dest)); + } + } + } + + let allow_unsound = + env::var("C2RUST_ANALYZE_PDG_ALLOW_UNSOUND").map_or(false, |val| &val == "1"); + for g in &graphs.graphs { for n in &g.nodes { let def_path_hash: (u64, u64) = n.function.id.0.into(); let ldid = match func_def_path_hash_to_ldid.get(&def_path_hash) { Some(&x) => x, None => { - panic!( + eprintln!( "pdg: unknown DefPathHash {:?} for function {:?}", n.function.id, n.function.name ); + continue; } }; let info = func_info.get_mut(&ldid).unwrap(); @@ -961,6 +985,8 @@ fn run(tcx: TyCtxt) { let mir = mir.borrow(); let acx = gacx.function_context_with_data(&mir, info.acx_data.take()); let mut asn = gasn.and(&mut info.lasn); + let mut updates_forbidden = + g_updates_forbidden.and_mut(&mut info.l_updates_forbidden); let dest_pl = match n.dest.as_ref() { Some(x) => x, @@ -976,6 +1002,14 @@ fn run(tcx: TyCtxt) { let dest = dest_pl.local; let dest = Local::from_u32(dest.index); + if acx.local_tys.get(dest).is_none() { + eprintln!( + "pdg: {}: local {:?} appears as dest, but is out of bounds", + n.function.name, dest + ); + info.acx_data.set(acx.into_data()); + continue; + } let ptr = match acx.ptr_of(dest) { Some(x) => x, None => { @@ -988,36 +1022,35 @@ fn run(tcx: TyCtxt) { } }; - let node_info = match n.info.as_ref() { - Some(x) => x, - None => { - eprintln!( - "pdg: {}: node with dest {:?} is missing NodeInfo", - n.function.name, dest - ); - info.acx_data.set(acx.into_data()); - continue; - } - }; - let old_perms = asn.perms()[ptr]; let mut perms = old_perms; - if node_info.flows_to.load.is_some() { - perms.insert(PermissionSet::READ); - } - if node_info.flows_to.store.is_some() { - perms.insert(PermissionSet::WRITE); - } - if node_info.flows_to.pos_offset.is_some() { - perms.insert(PermissionSet::OFFSET_ADD); - } - if node_info.flows_to.neg_offset.is_some() { - perms.insert(PermissionSet::OFFSET_SUB); + if known_nulls.contains(&(n.function.id, dest)) { + perms.remove(PermissionSet::NON_NULL); + } else if allow_unsound { + perms.insert(PermissionSet::NON_NULL); + // Unsound update: if we have never seen a NULL for + // this local in the PDG, prevent the static analysis + // from changing that permission. + updates_forbidden[ptr].insert(PermissionSet::NON_NULL); } - if !node_info.unique { - perms.remove(PermissionSet::UNIQUE); + + if let Some(node_info) = n.info.as_ref() { + if node_info.flows_to.load.is_some() { + perms.insert(PermissionSet::READ); + } + if node_info.flows_to.store.is_some() { + perms.insert(PermissionSet::WRITE); + } + if node_info.flows_to.pos_offset.is_some() { + perms.insert(PermissionSet::OFFSET_ADD); + } + if node_info.flows_to.neg_offset.is_some() { + perms.insert(PermissionSet::OFFSET_SUB); + } + if !node_info.unique { + perms.remove(PermissionSet::UNIQUE); + } } - // TODO: PermissionSet::NON_NULL if perms != old_perms { let added = perms & !old_perms; diff --git a/dynamic_instrumentation/Cargo.toml b/dynamic_instrumentation/Cargo.toml index fab4a52e2e..8dac511ca0 100644 --- a/dynamic_instrumentation/Cargo.toml +++ b/dynamic_instrumentation/Cargo.toml @@ -27,6 +27,7 @@ toml_edit = "0.19" fs2 = "0.4" env_logger = "0.10" tempfile = "3.3" +rand = "0.8.5" [build-dependencies] c2rust-build-paths = { path = "../c2rust-build-paths", version = "0.19.0" } diff --git a/dynamic_instrumentation/src/arg.rs b/dynamic_instrumentation/src/arg.rs index 94f85415fa..d85ae847d0 100644 --- a/dynamic_instrumentation/src/arg.rs +++ b/dynamic_instrumentation/src/arg.rs @@ -35,6 +35,7 @@ impl<'tcx> ArgKind<'tcx> { #[derive(Clone, Debug)] pub enum InstrumentationArg<'tcx> { AddrOf(Operand<'tcx>), + Pointer(Operand<'tcx>), Op(ArgKind<'tcx>), } @@ -42,7 +43,7 @@ impl<'tcx> InstrumentationArg<'tcx> { pub fn inner(&self) -> &Operand<'tcx> { use InstrumentationArg::*; match self { - AddrOf(x) => x, + AddrOf(x) | Pointer(x) => x, Op(x) => x.inner(), } } diff --git a/dynamic_instrumentation/src/instrument.rs b/dynamic_instrumentation/src/instrument.rs index ec31abd0ca..f1b2036a41 100644 --- a/dynamic_instrumentation/src/instrument.rs +++ b/dynamic_instrumentation/src/instrument.rs @@ -6,12 +6,15 @@ use fs2::FileExt; use fs_err::OpenOptions; use indexmap::IndexSet; use log::{debug, trace}; +use rand; 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, + BasicBlock, BasicBlockData, Body, ClearCrossCrate, HasLocalDecls, Local, LocalDecl, Location, + Operand, Place, PlaceElem, ProjectionElem, Rvalue, Safety, SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, START_BLOCK, }; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -24,8 +27,10 @@ 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::ProjectionSet; use crate::point::{cast_ptr_to_usize, InstrumentationPriority}; use crate::point::{ CollectAddressTakenLocals, CollectInstrumentationPoints, RewriteAddressTakenLocals, @@ -36,6 +41,7 @@ use crate::util::Convert; pub struct Instrumenter { mir_locs: Mutex>, functions: Mutex>, + projections: Mutex, u64>>, } impl Instrumenter { @@ -72,7 +78,18 @@ impl Instrumenter { let mut functions = self.functions.lock().unwrap(); let locs = locs.drain(..).collect::>(); let functions = functions.drain().collect::>(); - let metadata = Metadata { locs, functions }; + + let projections = std::mem::take(&mut *self.projections.lock().unwrap()); + let projections = projections + .into_iter() + .map(|(proj_vec, proj_key)| (proj_key, proj_vec)) + .collect(); + + let metadata = Metadata { + locs, + functions, + projections, + }; let bytes = bincode::serialize(&metadata).context("Location serialization failed")?; let mut file = OpenOptions::new() .append(true) @@ -113,6 +130,21 @@ impl Instrumenter { } } +impl ProjectionSet for Instrumenter { + fn add_proj(&self, proj: Vec) -> u64 { + // If this projection isn't already in the map, generate + // a random 64-bit key for it; the probability of collision + // is 1/2^32 (because of the birthday paradox), which should + // be good enough for our use case. + self.projections + .lock() + .unwrap() + .entry(proj) + .or_insert_with(rand::random) + .clone() + } +} + fn is_shared_or_unsafe_ptr(ty: Ty) -> bool { ty.is_unsafe_ptr() || (ty.is_region_ptr() && !ty.is_mutable_ptr()) } @@ -343,43 +375,197 @@ 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(); + + // 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 + // 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 + None => break (place.as_ref(), false), + _ => { + let _ = proj_iter.next(); + } + } + }; - let base_ty = self.local_decls()[place.local].ty; + // 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); - // 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 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 proj_key = self.projections.add_proj(fields); + + 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()) + .arg_var(proj_key) + .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) { let copy_fn = self.hooks().find("ptr_copy"); let addr_local_fn = self.hooks().find("addr_of_local"); + let addr_sized_fn = self.hooks().find("addr_of_sized"); let ptr_contrive_fn = self.hooks().find("ptr_contrive"); let ptr_to_int_fn = self.hooks().find("ptr_to_int"); let load_value_fn = self.hooks().find("load_value"); + let project_fn = self.hooks().find("ptr_project"); 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| { @@ -427,33 +613,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,28 +634,6 @@ 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) => { - // Instrument which local's address is taken - self.loc(location, location.successor_within_block(), addr_local_fn) - .arg_var(dest) - .arg_index_of(p.local) - .source(p) - .dest(&dest) - .instrumentation_priority(InstrumentationPriority::Early) - .add_to(self); - } Rvalue::Use(Operand::Copy(p) | Operand::Move(p)) if p.is_indirect() => { // We're dereferencing something, the result of which is a reference or pointer self.loc(location, location.successor_within_block(), load_value_fn) @@ -505,9 +644,8 @@ impl<'tcx> Visitor<'tcx> for CollectInstrumentationPoints<'_, 'tcx> { Rvalue::Use(Operand::Constant(..)) => { // Track (as copies) assignments that give local names to constants so that code // taking references to said constants can refer to these assignments as sources. - // TODO: should be replaced by AddrOfStatic when support for that is added - self.loc(location, location.successor_within_block(), copy_fn) - .arg_var(dest) + self.loc(location, location.successor_within_block(), addr_sized_fn) + .arg_ptr(dest) .dest(&dest) .debug_mir() .add_to(self); @@ -531,49 +669,46 @@ 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) + Rvalue::AddressOf(_, p) | Rvalue::Ref(_, _, p) if !p.is_indirect() => { 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 { - // Instrument which local's address is taken - self.loc(location, location, addr_local_fn) + let layout = ctx + .layout_of(ty::ParamEnv::reveal_all().and(local_ty(p))) + .expect("Failed to compute layout of local"); + let size = + u32::try_from(layout.size.bytes()).expect("Failed to convert local size"); + + let mut b = self + .loc(location, location, addr_local_fn) + .arg_addr_of(p.local) + .arg_index_of(p.local) + .arg_var(size) + .source(&source) + .instrumentation_priority(InstrumentationPriority::Early); + if p.projection.is_empty() { + // No projections, store directly to the destination + b = b.dest(&dest); + } + b.add_to(self); + + if !p.projection.is_empty() { + let fields = p + .projection + .iter() + .filter_map(|elem| match elem { + PlaceElem::Field(idx, _) => Some(idx.index()), + _ => None, + }) + .collect::>(); + let proj_idx = self.projections.add_proj(fields); + + self.loc(location, location, project_fn) + .arg_addr_of(p.local) .arg_addr_of(*p) - .arg_index_of(p.local) - .source(&source) + .arg_var(proj_idx) .dest(&dest) .instrumentation_priority(InstrumentationPriority::Early) .add_to(self); - } else { - // Instrument immutable borrows by tracing the reference itself - self.loc(location, location.successor_within_block(), addr_local_fn) - .arg_var(dest) - .arg_index_of(p.local) - .source(&source) - .dest(&dest) - .instrumentation_priority(InstrumentationPriority::Early) - .add_to(self); - }; + } } _ => (), } @@ -715,7 +850,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() }; @@ -789,12 +925,14 @@ pub fn insert_call<'tcx>( is_cleanup: blocks[block].is_cleanup, }); + let mut ty_substs: Vec = vec![]; for arg in &mut args { - if let Some((cast_stmts, cast_local)) = cast_ptr_to_usize(tcx, locals, arg) { + if let Some((cast_stmts, cast_local, ty_subst)) = cast_ptr_to_usize(tcx, locals, arg) { *arg = InstrumentationArg::Op(ArgKind::AddressUsize(cast_local)); blocks[block] .statements .splice(statement_index..statement_index, cast_stmts); + ty_substs.extend(ty_subst.into_iter().map(ty::GenericArg::from)); } } @@ -802,7 +940,7 @@ pub fn insert_call<'tcx>( let fn_sig = tcx.liberate_late_bound_regions(func, fn_sig); let ret_local = locals.push(LocalDecl::new(fn_sig.output(), DUMMY_SP)); - let func = Operand::function_handle(tcx, func, ty::List::empty(), DUMMY_SP); + let func = Operand::function_handle(tcx, func, tcx.mk_substs(ty_substs.into_iter()), DUMMY_SP); let call = Terminator { kind: TerminatorKind::Call { diff --git a/dynamic_instrumentation/src/into_operand.rs b/dynamic_instrumentation/src/into_operand.rs index fcf0c4ed58..980221d69c 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,17 +10,55 @@ 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) } } +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 u64 { + 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.u64), + )), + })) + } +} + 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/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/dynamic_instrumentation/src/point/apply.rs b/dynamic_instrumentation/src/point/apply.rs index 52e8f6830c..823d909278 100644 --- a/dynamic_instrumentation/src/point/apply.rs +++ b/dynamic_instrumentation/src/point/apply.rs @@ -111,7 +111,12 @@ impl<'tcx, 'a> InstrumentationApplier<'tcx, 'a> { }; // push return value to argument list - if let Some((casts, cast_local)) = cast_ptr_to_usize(tcx, locals, &ret_value) { + if let Some((casts, cast_local, ty)) = cast_ptr_to_usize(tcx, locals, &ret_value) { + assert!( + ty.is_none(), + "Got a type substitution for call result: {:?}", + call + ); extra_statements = Some(casts); args.push(InstrumentationArg::Op(ArgKind::AddressUsize(cast_local))); } else { diff --git a/dynamic_instrumentation/src/point/build.rs b/dynamic_instrumentation/src/point/build.rs index bc5d9c24e5..b580622d10 100644 --- a/dynamic_instrumentation/src/point/build.rs +++ b/dynamic_instrumentation/src/point/build.rs @@ -136,6 +136,13 @@ impl<'tcx> InstrumentationBuilder<'_, 'tcx> { self } + /// Add an argument to this [`InstrumentationPoint`] that copies the pointer as is. + pub fn arg_ptr(mut self, arg: impl IntoOperand<'tcx>) -> Self { + let op = arg.op(self.tcx); + self.point.args.push(InstrumentationArg::Pointer(op)); + self + } + pub fn after_call(mut self) -> Self { self.point.after_call = true; self diff --git a/dynamic_instrumentation/src/point/cast.rs b/dynamic_instrumentation/src/point/cast.rs index 6ab29aeff8..53d92c5be8 100644 --- a/dynamic_instrumentation/src/point/cast.rs +++ b/dynamic_instrumentation/src/point/cast.rs @@ -4,7 +4,7 @@ use rustc_middle::{ CastKind, Local, LocalDecl, Mutability, Operand, ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, }, - ty::{self, TyCtxt, TypeAndMut}, + ty::{self, adjustment::PointerCast, Ty, TyCtxt, TypeAndMut}, }; use rustc_span::DUMMY_SP; @@ -21,7 +21,7 @@ pub fn cast_ptr_to_usize<'tcx>( tcx: TyCtxt<'tcx>, locals: &mut IndexVec>, arg: &InstrumentationArg<'tcx>, -) -> Option<(Vec>, Operand<'tcx>)> { +) -> Option<(Vec>, Operand<'tcx>, Option>)> { let mut new_stmts = vec![]; let arg_ty = arg.inner().ty(locals, tcx); @@ -93,6 +93,53 @@ pub fn cast_ptr_to_usize<'tcx>( new_stmts.push(addr_of_stmt); Operand::Move(raw_ptr_local.into()) } + // We want to preserve the operand as a pointer, e.g., for `AddrOfSized`. + // The argument might be a reference, so we need to do a double cast, e.g. + // `&x` => `&x as *const T` and `&mut x` => `&mut x as *mut T as *const T` + InstrumentationArg::Pointer(arg) => { + let inner_ty = arg_ty + .builtin_deref(true) + .expect("Expected pointer or reference"); + + let mut new_arg = arg.clone(); + if !arg_ty.is_unsafe_ptr() { + // First cast: from non-pointer to pointer + let arg_place = arg.place().expect("Can't get the address of a constant"); + let arg_deref = tcx.mk_place_deref(arg_place); + let raw_ptr_ty = tcx.mk_ptr(inner_ty); + let raw_ptr_local = locals.push(LocalDecl::new(raw_ptr_ty, DUMMY_SP)); + let cast_stmt = Statement { + source_info: SourceInfo::outermost(DUMMY_SP), + kind: StatementKind::Assign(Box::new(( + raw_ptr_local.into(), + Rvalue::AddressOf(inner_ty.mutbl, arg_deref), + ))), + }; + new_stmts.push(cast_stmt); + new_arg = Operand::Move(raw_ptr_local.into()); + } + + if arg_ty.is_mutable_ptr() { + // Second cast: cast away the mutability + let raw_ptr_ty = tcx.mk_imm_ptr(inner_ty.ty); + let raw_ptr_local = locals.push(LocalDecl::new(raw_ptr_ty, DUMMY_SP)); + let cast_stmt = Statement { + source_info: SourceInfo::outermost(DUMMY_SP), + kind: StatementKind::Assign(Box::new(( + raw_ptr_local.into(), + Rvalue::Cast( + CastKind::Pointer(PointerCast::MutToConstPointer), + new_arg, + raw_ptr_ty, + ), + ))), + }; + new_stmts.push(cast_stmt); + new_arg = Operand::Move(raw_ptr_local.into()); + } + + return Some((new_stmts, new_arg, Some(inner_ty.ty))); + } }; let ptr = { @@ -126,5 +173,5 @@ pub fn cast_ptr_to_usize<'tcx>( ))), }; new_stmts.push(cast_stmt); - Some((new_stmts, casted_arg)) + Some((new_stmts, casted_arg, None)) } diff --git a/dynamic_instrumentation/src/point/mod.rs b/dynamic_instrumentation/src/point/mod.rs index 1b3a069c3f..ec062349cb 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) -> u64; +} + 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 e8b30ef3e4..85f4ea8b53 100644 --- a/pdg/src/builder.rs +++ b/pdg/src/builder.rs @@ -6,7 +6,7 @@ use color_eyre::eyre; use fs_err::File; use indexmap::IndexSet; use itertools::Itertools; -use std::collections::HashMap; +use std::collections::BTreeMap; use std::io::{self, BufReader}; use std::iter; use std::path::Path; @@ -23,10 +23,10 @@ pub fn read_metadata(path: &Path) -> eyre::Result { Ok(Metadata::read(&bytes)?) } -fn parent(e: &NodeKind, obj: (GraphId, NodeId)) -> Option<(GraphId, NodeId)> { +fn parent<'a, 'b>(e: &'a NodeKind, obj: &'b ProvenanceInfo) -> Option<&'b ProvenanceInfo> { use NodeKind::*; match e { - Alloc(..) | AddrOfLocal(..) => None, + Alloc(..) | AddrOfLocal(..) | AddrOfSized(..) => None, _ => Some(obj), } } @@ -35,7 +35,12 @@ type AddressTaken = IndexSet<(FuncId, Local)>; pub trait EventKindExt { fn ptr(&self, metadata: &EventMetadata) -> Option; - fn to_node_kind(&self, func: FuncId, address_taken: &mut AddressTaken) -> Option; + fn to_node_kind( + &self, + func: FuncId, + metadata: &Metadata, + address_taken: &mut AddressTaken, + ) -> Option; } impl EventKindExt for EventKind { @@ -44,7 +49,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, @@ -52,31 +57,42 @@ impl EventKindExt for EventKind { StoreAddrTaken(ptr) => ptr, LoadValue(ptr) => ptr, StoreValue(ptr) => ptr, - CopyRef => return None, // FIXME ToInt(ptr) => ptr, Realloc { old_ptr, .. } => old_ptr, FromInt(lhs) => lhs, Alloc { ptr, .. } => ptr, - AddrOfLocal(lhs, _) => lhs, + AddrOfLocal { ptr, .. } => ptr, + AddrOfSized { ptr, .. } => ptr, Offset(ptr, _, _) => ptr, Done | BeginFuncBody => return None, }) } - fn to_node_kind(&self, func: FuncId, address_taken: &mut AddressTaken) -> Option { + fn to_node_kind( + &self, + func: FuncId, + metadata: &Metadata, + address_taken: &mut AddressTaken, + ) -> Option { use EventKind::*; Some(match *self { Alloc { .. } => NodeKind::Alloc(1), Realloc { .. } => NodeKind::Alloc(1), Free { .. } => NodeKind::Free, - CopyPtr(..) | CopyRef => NodeKind::Copy, - Field(_, field) => NodeKind::Field(field.into()), + CopyPtr(..) => NodeKind::Copy, + Project(base_ptr, new_ptr, key) => { + let proj = metadata + .projections + .get(&key) + .expect("Invalid projection metadata"); + NodeKind::Project(new_ptr - base_ptr, proj.clone()) + } LoadAddr(..) => NodeKind::LoadAddr, StoreAddr(..) => NodeKind::StoreAddr, StoreAddrTaken(..) => NodeKind::StoreAddr, LoadValue(..) => NodeKind::LoadValue, StoreValue(..) => NodeKind::StoreValue, - AddrOfLocal(_, local) => { + AddrOfLocal { local, .. } => { // All but the first instance of AddrOfLocal in a given // function body are considered copies of that local's address let (_, inserted) = address_taken.insert_full((func, local)); @@ -86,6 +102,7 @@ impl EventKindExt for EventKind { NodeKind::Copy } } + AddrOfSized { size, .. } => NodeKind::AddrOfSized(size), BeginFuncBody => { // Reset the collection of address-taken locals, in order to // properly consider the first instance of each address-taking @@ -102,42 +119,117 @@ impl EventKindExt for EventKind { } } +#[derive(Debug, Clone)] +pub struct ProvenanceInfo { + /// Size of this allocation or local object. + size: Option, + + /// Graph containing all the nodes for this object. + gid: GraphId, + + /// One node that created this object. + nid: NodeId, +} + +impl ProvenanceInfo { + fn new(gid: GraphId, nid: NodeId) -> Self { + Self { + size: None, + gid, + nid, + } + } + + /// Return a copy of the current object with a different node. + fn with_node(&self, nid: NodeId) -> Self { + Self { + nid, + ..self.clone() + } + } +} + fn update_provenance( - provenances: &mut HashMap, + provenances: &mut BTreeMap, event_kind: &EventKind, - metadata: &EventMetadata, - mapping: (GraphId, NodeId), + mut mapping: ProvenanceInfo, ) { use EventKind::*; match *event_kind { - Alloc { ptr, .. } => { + Alloc { ptr, size, .. } => { + // TODO: check for overlap with existing allocations + mapping.size = Some(size); provenances.insert(ptr, mapping); } - CopyPtr(ptr) => { - // only insert if not already there - if let Err(..) = provenances.try_insert(ptr, mapping) { - log::warn!("0x{:x} already has a source", ptr); - } - } - Realloc { new_ptr, .. } => { + Realloc { new_ptr, size, .. } => { + mapping.size = Some(size); provenances.insert(new_ptr, mapping); } - Offset(_, _, new_ptr) => { - provenances.insert(new_ptr, mapping); + Free { ptr } if ptr != 0 => { + // TODO: handle the case where `ptr` falls inside an allocation + let old_prov = provenances.remove(&ptr); + if old_prov.is_none() { + log::warn!("Tried to free invalid pointer 0x{:x}", ptr); + } } - CopyRef => { - provenances.insert(metadata.destination.clone().unwrap().local.into(), mapping); + CopyPtr(ptr) | Offset(_, _, ptr) | Project(_, ptr, _) => { + // Check that the pointer falls inside an existing allocation + let need_insert = provenances + .range(0..=ptr) + .next_back() + .map(|(start, pi)| { + // If the existing pointer has a size, check it + // Otherwise, insert ours if it's different + let size = match pi.size { + Some(size) => size, + None => return ptr != *start, + }; + + let end = start.saturating_add(size); + if (*start..=end).contains(&ptr) { + return false; + } + + if matches!(*event_kind, CopyPtr(_)) { + // A new pointer that we don't know where it came from + // Insert it for now, we should decide later what to do + // + // Assume an unknown pointer points to a word-sized object + log::warn!("Pointer of unknown origin 0x{:x}", ptr); + return true; + } + + log::warn!( + "0x{:x} outside of object bounds 0x{:x}-0x{:x}", + ptr, + start, + end + ); + + false + }) + .unwrap_or(true); + + if need_insert { + provenances.insert(ptr, mapping); + } } - AddrOfLocal(ptr, _) => { + AddrOfLocal { ptr, size, .. } => { + // TODO: is this a local from another function? + mapping.size = size.try_into().ok(); provenances.insert(ptr, mapping); } + AddrOfSized { ptr, size } => { + mapping.size = Some(size); + let _ = provenances.try_insert(ptr, mapping); + } _ => {} } } pub fn add_node( graphs: &mut Graphs, - provenances: &mut HashMap, + provenances: &mut BTreeMap, address_taken: &mut AddressTaken, event: &Event, metadata: &Metadata, @@ -149,9 +241,9 @@ pub fn add_node( metadata: event_metadata, } = metadata.get(event.mir_loc); - let node_kind = event.kind.to_node_kind(func.id, address_taken)?; + let node_kind = event.kind.to_node_kind(func.id, metadata, 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), @@ -163,47 +255,54 @@ pub fn add_node( statement_idx = 0; } - let provenance = event - .kind - .ptr(event_metadata) - .and_then(|ptr| provenances.get(&ptr).cloned()); - let direct_source = provenance.and_then(|(gid, _last_nid_ref)| { - graphs.graphs[gid] + let ptr = event.kind.ptr(event_metadata); + let provenance = ptr.and_then(|ptr| { + provenances + .range(0..=ptr) + .next_back() + .and_then(|(start, pi)| { + let size = match pi.size { + Some(size) => size, + None if ptr == *start => return Some(pi), + None => return None, + }; + + // If the current pointer falls outside the + // original object, make a new graph for it + let end = start.saturating_add(size); + + // This is intentionally greater-than because + // one past the end is still a valid pointer + if ptr > end { + None + } else { + Some(pi) + } + }) + }); + + let direct_source = provenance.and_then(|pi| { + graphs.graphs[pi.gid] .nodes .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::Field(..) = n.kind { - return Some((gid, nid)); - } - } - } - } - - if !matches!(event.kind, EventKind::AddrOfLocal(..)) && src.projection.is_empty() { - latest_assignment - } else if let EventKind::Field(..) = event.kind { - latest_assignment - } else { - provenance - } - }) + .map(|nid| pi.with_node(NodeId::from(nid))) }); + let source = direct_source.or(provenance.cloned()); let function = Func { id: dest_fn, @@ -214,56 +313,47 @@ pub fn add_node( function, block: basic_block_idx.into(), statement_idx, - kind: node_kind, + kind: node_kind.clone(), source: source + .as_ref() .and_then(|p| parent(&node_kind, p)) - .map(|(_, nid)| nid), + .map(|pi| pi.nid), dest: event_metadata.destination.clone(), debug_info: event_metadata.debug_info.clone(), info: None, }; + let ptr_is_null = ptr.map_or(false, |ptr| ptr == 0); let graph_id = source - .or(direct_source) - .or(provenance) + .as_ref() .and_then(|p| parent(&node_kind, p)) - .map(|(gid, _)| gid) - .unwrap_or_else(|| graphs.graphs.push(Graph::new())); + .map(|pi| pi.gid) + .unwrap_or_else(|| graphs.graphs.push(Graph::new(ptr_is_null))); let node_id = graphs.graphs[graph_id].nodes.push(node); + // Assert that we're not mixing null and non-null pointers + assert!( + graphs.graphs[graph_id].is_null == ptr_is_null, + "graph[{}].is_null == {:?} != {:x?} for {:?}:{:?}", + graph_id, + graphs.graphs[graph_id].is_null, + ptr, + event, + event_metadata + ); + update_provenance( provenances, &event.kind, - event_metadata, - (graph_id, node_id), + ProvenanceInfo::new(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) } pub fn construct_pdg(events: &[Event], metadata: &Metadata) -> Graphs { let mut graphs = Graphs::new(); - let mut provenances = HashMap::new(); + let mut provenances = BTreeMap::new(); let mut address_taken = AddressTaken::new(); for event in events { add_node( diff --git a/pdg/src/graph.rs b/pdg/src/graph.rs index e921018e9a..5b55037057 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::{ @@ -14,7 +14,7 @@ use crate::info::NodeInfo; use crate::util::pad_columns; use crate::util::ShortOption; -#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy, Serialize, Deserialize)] +#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)] pub enum NodeKind { /// A copy from one [`Local`] to another. /// @@ -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, Vec), /// Pointer arithmetic. /// @@ -59,6 +57,9 @@ pub enum NodeKind { /// Can't have a [`Node::source`]. _AddrOfStatic(DefPathHash), + /// Get the address of a sized value. + AddrOfSized(usize), + /// Heap allocation. /// /// The [`usize`] is the number of array elements allocated @@ -121,10 +122,11 @@ impl Display for NodeKind { use NodeKind::*; match self { Copy => write!(f, "copy"), - Field(field) => write!(f, "field.{}", field.as_usize()), + Project(offset, proj) => write!(f, "project{proj:?}@{offset}"), Offset(offset) => write!(f, "offset[{offset}]"), AddrOfLocal(local) => write!(f, "&{local:?}"), _AddrOfStatic(static_) => write!(f, "&'static {static_:?}"), + AddrOfSized(size) => write!(f, "sized({size})"), Alloc(n) => { // Right now we only create `Alloc(1)`, so special case it, // as the increased readability helps. @@ -281,18 +283,24 @@ impl Display for DisplayNode<'_> { } /// A pointer derivation graph, which tracks the handling of one object throughout its lifetime. -#[derive(Debug, Default, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)] +#[derive(Debug, Eq, PartialEq, Hash, Clone, Serialize, Deserialize)] pub struct Graph { /// The nodes in the graph. Nodes are stored in increasing order by timestamp. The first /// node, called the "root node", creates the object described by this graph, and all other /// nodes are derived from it. #[serde(with = "crate::util::serde::index_vec")] pub nodes: IndexVec, + + /// Whether this graph was built from a null pointer. + pub is_null: bool, } impl Graph { - pub fn new() -> Self { - Self::default() + pub fn new(is_null: bool) -> Self { + Self { + nodes: Default::default(), + is_null, + } } } @@ -311,7 +319,7 @@ impl Display for Graph { .to_string() }) .collect::>(); - writeln!(f, "g {{")?; + writeln!(f, "g is_null={} {{", self.is_null)?; for line in pad_columns(&lines, sep, " ") { let line = line.trim_end(); writeln!(f, "\t{line}")?; diff --git a/pdg/src/info.rs b/pdg/src/info.rs index ad26b23e5f..b38baa7daa 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 and projection index vector. +type Field = Vec; + /// Information generated from the PDG proper that is queried by static analysis. /// /// Includes information about what kinds of [`Node`]s the [`Node`] flows to, @@ -57,7 +59,7 @@ fn set_flow_info(g: &mut Graph) { let mut flow_map: HashMap = HashMap::from_iter( g.nodes .iter_enumerated() - .map(|(idx, node)| (idx, FlowInfo::new(idx, node.kind))), + .map(|(idx, node)| (idx, FlowInfo::new(idx, node.kind.clone()))), ); for (n_id, mut node) in g.nodes.iter_enumerated_mut().rev() { let cur_node_flow_info: FlowInfo = flow_map.remove(&n_id).unwrap(); @@ -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) @@ -121,7 +123,7 @@ fn collect_children(g: &Graph) -> HashMap)>> { ( gchild, ({ - gchildf.push(f); + gchildf.push(f.clone()); gchildf }), ) @@ -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,9 @@ 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 { + let f = field.into(); + mk_node(g, NodeKind::Project(f.iter().sum(), f), Some(source)) } fn mk_offset(g: &mut Graph, source: NodeId, i: isize) -> NodeId { @@ -296,7 +298,7 @@ mod test { /// ``` #[test] fn unique_interleave() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = 0; let a = mk_addr_of_local(&mut g, 0_u32); @@ -344,7 +346,7 @@ mod test { /// ``` #[test] fn unique_interleave_onesided() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = 0; // A let a = mk_addr_of_local(&mut g, 0_u32); @@ -388,7 +390,7 @@ mod test { /// ``` #[test] fn unique_sub_borrow() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = 0; let a = mk_addr_of_local(&mut g, 0_u32); @@ -434,7 +436,7 @@ mod test { /// ``` #[test] fn unique_sub_borrow_bad() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = 0; let a = mk_addr_of_local(&mut g, 0_u32); @@ -480,15 +482,15 @@ mod test { /// ``` #[test] fn okay_use_different_fields() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = Point { x: 0, y: 0 }; let a = mk_addr_of_local(&mut g, 0_u32); // let b = &mut a.x; - let b11 = mk_field(&mut g, a, 0_u32); + let b11 = mk_project(&mut g, a, vec![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, vec![1_usize]); let c1 = mk_copy(&mut g, c11); // *b = 1; let b2 = mk_store_addr(&mut g, b1); @@ -528,24 +530,24 @@ mod test { /// ``` #[test] fn same_fields_cousins() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = Point { x: 0, y: 0 }; let a = mk_addr_of_local(&mut g, 0_u32); // 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, vec![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, vec![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, vec![1_usize]); let d2 = mk_store_addr(&mut g, d1); let pdg = build_pdg(g); @@ -577,14 +579,14 @@ mod test { /// ``` #[test] fn field_vs_raw() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = Point { x: 0, y: 0 }; let a = mk_addr_of_local(&mut g, 0_u32); // 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, vec![1_usize]); let c1 = mk_copy(&mut g, c11); // *c = 2; let c2 = mk_store_addr(&mut g, c1); @@ -623,17 +625,17 @@ mod test { /// ``` #[test] fn fields_different_levels() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = Point { x: 0, y: 0 }; let a = mk_addr_of_local(&mut g, 0_u32); // 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, vec![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, vec![1_usize]); let bb1 = mk_copy(&mut g, bb); // *c = 2; let c3 = mk_store_addr(&mut g, c2); @@ -667,22 +669,22 @@ mod test { /// ``` #[test] fn lots_of_siblings() { - let mut g = Graph::default(); + let mut g = Graph::new(false); - let (x, y, z) = (0_u32, 1_u32, 2_u32); - let (red, green, _blue) = (0_u32, 1_u32, 2_u32); + let (x, y, z) = (vec![0_usize], vec![1_usize], vec![2_usize]); + let (red, green, _blue) = (vec![0_usize], vec![1_usize], vec![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.clone()); + 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 +695,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.clone()); 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.clone()); 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.clone()); 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); @@ -753,15 +755,15 @@ mod test { /// ``` #[test] fn field_no_conflict() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0; - let x1 = mk_field(&mut g, a, 0_u32); + let x1 = mk_project(&mut g, a, vec![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, vec![1_usize]); let y2 = mk_copy(&mut g, y1); // *x = 1; let x3 = mk_store_addr(&mut g, x2); @@ -811,17 +813,17 @@ mod test { /// ``` #[test] fn nested_field_no_conflict() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // 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, vec![1_usize]); + let x2 = mk_project(&mut g, x1, vec![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, vec![1_usize]); + let y2 = mk_project(&mut g, y1, vec![1_usize]); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); @@ -865,21 +867,21 @@ mod test { /// ``` #[test] fn diff_field_conflict() { - let mut g = Graph::default(); + let mut g = Graph::new(false); //let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); //let mut x = &mut a.1; - let x1 = mk_field(&mut g, a, 1_u32); + let x1 = mk_project(&mut g, a, vec![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, vec![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, vec![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, vec![1_usize]); let y4 = mk_store_addr(&mut g, y3); let pdg = build_pdg(g); @@ -919,17 +921,17 @@ mod test { /// ``` #[test] fn nested_field_conflict() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = (1, (2, 3)); let a = mk_addr_of_local(&mut g, 0_u32); // 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, vec![1_usize]); + let x2 = mk_project(&mut g, x1, vec![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, vec![1_usize]); + let y2 = mk_project(&mut g, y1, vec![0_usize]); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); @@ -981,16 +983,16 @@ mod test { /// ``` #[test] fn field_offset_conflict() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = ([1, 2], [3, 4]); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0[0]; - let x1 = mk_field(&mut g, a, 1_u32); + let x1 = mk_project(&mut g, a, vec![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, vec![1_usize]); let y2 = mk_offset(&mut g, y1, 1); let y3 = mk_copy(&mut g, y2); // *x = 1; @@ -1043,16 +1045,16 @@ mod test { /// ``` #[test] fn field_offset_no_conflict() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = ([1, 2], [3, 4]); let a = mk_addr_of_local(&mut g, 0_u32); // let x = &mut a.0[0]; - let x1 = mk_field(&mut g, a, 0_u32); + let x1 = mk_project(&mut g, a, vec![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, vec![1_usize]); let y2 = mk_offset(&mut g, y1, 0); let y3 = mk_copy(&mut g, y2); // *x = 1; @@ -1113,18 +1115,18 @@ mod test { /// `rustc` would reject the modified code. #[test] fn offset_field_conflict() { - let mut g = Graph::default(); + let mut g = Graph::new(false); // let mut a = ([1, 2], [3, 4]); // let p = &mut a; 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, vec![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, vec![1_usize]); let y3 = mk_copy(&mut g, y2); // *x = 1; let x4 = mk_store_addr(&mut g, x3); 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..0e01ad109b 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,35 +1,47 @@ --- source: pdg/src/main.rs +assertion_line: 376 expression: pdg --- -g { +g is_null=false { n[0]: &_1 _ => _ @ bb3[0]: fn main; _23 = &raw mut _1; n[1]: copy n[0] => _11 @ bb3[10]: fn main; _11 = &(*_23); n[2]: copy n[1] => _1 @ bb0[0]: fn deref; _10 = deref(move _11); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: copy _ => _10 @ bb3[11]: fn main; _10 = deref(move _11); n[1]: copy n[0] => _9 @ bb4[0]: fn main; _9 = &(*_10); n[2]: copy n[1] => _1 @ bb0[0]: fn iter; _8 = iter(move _9); } 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); +g is_null=true { + 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 n[0] => _17 @ bb4[29]: fn simple; _17 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[3]: copy n[0] => _23 @ bb5[4]: fn simple; _23 = null_mut(); + n[4]: copy n[3] => _2 @ bb0[0]: fn recur; _22 = recur(const 3_i32, move _23); + n[5]: copy n[4] => _17 @ bb15[3]: fn recur; _17 = _2; + n[6]: copy n[5] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _17); + n[7]: copy n[6] => _17 @ bb15[3]: fn recur; _17 = _2; + n[8]: copy n[7] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _17); + n[9]: copy n[8] => _17 @ bb15[3]: fn recur; _17 = _2; + n[10]: copy n[9] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _17); + n[11]: copy n[10] => _9 @ bb1[3]: fn recur; _9 = _2; + n[12]: copy n[11] => _1 @ bb0[0]: fn is_null; _8 = is_null(move _9); + n[13]: copy n[10] => _18 @ bb16[4]: fn recur; _18 = _2; + n[14]: copy n[10] => _18 @ bb16[4]: fn recur; _18 = _2; + n[15]: copy n[10] => _18 @ bb16[4]: fn recur; _18 = _2; + n[16]: value.store n[0] => _20.* @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); + n[17]: value.store n[0] => _17.* @ bb8[4]: fn fdevent_unregister; (*_17) = const 0_usize as *mut pointers::fdnode_st (PointerFromExposedAddress); + n[18]: int_to_ptr n[0] => _50 @ bb35[3]: fn main_0; _50 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[19]: 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 = [] -g { +g is_null=false { n[0]: &_5 _ => _ @ bb10[0]: fn main; _24 = &raw mut _5; n[1]: copy n[0] => _19 @ bb10[9]: fn main; _19 = &(*_24); n[2]: copy n[1] => _1 @ bb0[0]: fn len; _18 = len(move _19); @@ -37,358 +49,410 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: copy _ => _21 @ bb12[7]: fn main; _21 = as_mut_ptr(move _22); n[1]: copy n[0] => _2 @ bb0[0]: fn main_0; _15 = main_0(move _16, move _21); } 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); +g is_null=false { + 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] => _26 @ bb7[5]: fn simple; _26 = _5; + n[5]: copy n[4] => _25 @ bb7[6]: fn simple; _25 = move _26 as *mut libc::c_void (Misc); + n[6]: free n[5] => _24 @ bb7[8]: fn simple; _24 = free(move _25); } 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); +g is_null=false { + 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] => _17 @ bb15[3]: fn recur; _17 = _2; + n[26]: copy n[25] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _17); + n[27]: copy n[26] => _17 @ bb15[3]: fn recur; _17 = _2; + n[28]: copy n[27] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _17); + n[29]: copy n[28] => _17 @ bb15[3]: fn recur; _17 = _2; + n[30]: copy n[29] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _17); + n[31]: copy n[30] => _9 @ bb1[3]: fn recur; _9 = _2; + n[32]: copy n[31] => _1 @ bb0[0]: fn is_null; _8 = is_null(move _9); + n[33]: copy n[30] => _12 @ bb9[4]: fn recur; _12 = _2; + n[34]: copy n[33] => _11 @ bb9[5]: fn recur; _11 = move _12 as *mut libc::c_void (Misc); + n[35]: free n[34] => _0 @ bb9[7]: fn recur; _0 = free(move _11); +} +nodes_that_need_write = [22, 20, 17, 11, 9, 5, 3, 2, 1, 0] + +g is_null=false { + n[0]: copy _ => _18 @ bb16[4]: fn recur; _18 = _2; + n[1]: copy n[0] => _18 @ bb16[4]: fn recur; _18 = _2; + n[2]: copy n[0] => _18 @ bb16[4]: fn recur; _18 = _2; } 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); +g is_null=false { + 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 = [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"; - n[1]: copy n[0] => _8 @ bb2[12]: fn exercise_allocator; _8 = &raw const (*_9); - 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[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[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[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[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[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[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[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[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[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[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[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[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[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[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); - n[74]: copy n[73] => _1 @ bb0[0]: fn printf; _13 = printf(move _14, move _18); +g is_null=false { + n[0]: sized(4) _ => _9 @ bb2[11]: fn exercise_allocator; _9 = const b"%i\n\x00"; + n[1]: copy n[0] => _8 @ bb2[12]: fn exercise_allocator; _8 = &raw const (*_9); + 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 n[0] => _30 @ bb11[6]: fn exercise_allocator; _30 = &raw const (*_31); + n[6]: copy n[5] => _29 @ bb11[7]: fn exercise_allocator; _29 = move _30 as *const u8 (Pointer(ArrayToPointer)); + n[7]: copy n[6] => _28 @ bb11[9]: fn exercise_allocator; _28 = move _29 as *const i8 (Misc); + n[8]: copy n[7] => _1 @ bb0[0]: fn printf; _27 = printf(move _28, move _32); + n[9]: copy n[0] => _30 @ bb11[6]: fn exercise_allocator; _30 = &raw const (*_31); + n[10]: copy n[9] => _29 @ bb11[7]: fn exercise_allocator; _29 = move _30 as *const u8 (Pointer(ArrayToPointer)); + n[11]: copy n[10] => _28 @ bb11[9]: fn exercise_allocator; _28 = move _29 as *const i8 (Misc); + n[12]: copy n[11] => _1 @ bb0[0]: fn printf; _27 = printf(move _28, move _32); + n[13]: copy n[0] => _60 @ bb29[6]: fn exercise_allocator; _60 = &raw const (*_61); + n[14]: copy n[13] => _59 @ bb29[7]: fn exercise_allocator; _59 = move _60 as *const u8 (Pointer(ArrayToPointer)); + n[15]: copy n[14] => _58 @ bb29[9]: fn exercise_allocator; _58 = move _59 as *const i8 (Misc); + n[16]: copy n[15] => _1 @ bb0[0]: fn printf; _57 = printf(move _58, move _62); + n[17]: copy n[0] => _60 @ bb29[6]: fn exercise_allocator; _60 = &raw const (*_61); + n[18]: copy n[17] => _59 @ bb29[7]: fn exercise_allocator; _59 = move _60 as *const u8 (Pointer(ArrayToPointer)); + n[19]: copy n[18] => _58 @ bb29[9]: fn exercise_allocator; _58 = move _59 as *const i8 (Misc); + n[20]: copy n[19] => _1 @ bb0[0]: fn printf; _57 = printf(move _58, move _62); + n[21]: copy n[0] => _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 n[0] => _93 @ bb49[6]: fn exercise_allocator; _93 = &raw const (*_94); + n[26]: copy n[25] => _92 @ bb49[7]: fn exercise_allocator; _92 = move _93 as *const u8 (Pointer(ArrayToPointer)); + n[27]: copy n[26] => _91 @ bb49[9]: fn exercise_allocator; _91 = move _92 as *const i8 (Misc); + n[28]: copy n[27] => _1 @ bb0[0]: fn printf; _90 = printf(move _91, move _95); + n[29]: copy n[0] => _93 @ bb49[6]: fn exercise_allocator; _93 = &raw const (*_94); + n[30]: copy n[29] => _92 @ bb49[7]: fn exercise_allocator; _92 = move _93 as *const u8 (Pointer(ArrayToPointer)); + n[31]: copy n[30] => _91 @ bb49[9]: fn exercise_allocator; _91 = move _92 as *const i8 (Misc); + n[32]: copy n[31] => _1 @ bb0[0]: fn printf; _90 = printf(move _91, move _95); + n[33]: copy n[0] => _93 @ bb49[6]: fn exercise_allocator; _93 = &raw const (*_94); + n[34]: copy n[33] => _92 @ bb49[7]: fn exercise_allocator; _92 = move _93 as *const u8 (Pointer(ArrayToPointer)); + n[35]: copy n[34] => _91 @ bb49[9]: fn exercise_allocator; _91 = move _92 as *const i8 (Misc); + n[36]: copy n[35] => _1 @ bb0[0]: fn printf; _90 = printf(move _91, move _95); + n[37]: copy n[0] => _93 @ bb49[6]: fn exercise_allocator; _93 = &raw const (*_94); + n[38]: copy n[37] => _92 @ bb49[7]: fn exercise_allocator; _92 = move _93 as *const u8 (Pointer(ArrayToPointer)); + n[39]: copy n[38] => _91 @ bb49[9]: fn exercise_allocator; _91 = move _92 as *const i8 (Misc); + n[40]: copy n[39] => _1 @ bb0[0]: fn printf; _90 = printf(move _91, move _95); + n[41]: copy n[0] => _8 @ bb2[12]: fn simple_analysis; _8 = &raw const (*_9); + n[42]: copy n[41] => _7 @ bb2[13]: fn simple_analysis; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); + n[43]: copy n[42] => _6 @ bb2[15]: fn simple_analysis; _6 = move _7 as *const i8 (Misc); + n[44]: copy n[43] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); + n[45]: copy n[43] => _5 @ bb0[6]: fn analysis2_helper; _5 = &raw const (*_6); + n[46]: copy n[45] => _4 @ bb0[7]: fn analysis2_helper; _4 = move _5 as *const u8 (Pointer(ArrayToPointer)); + n[47]: copy n[46] => _3 @ bb0[9]: fn analysis2_helper; _3 = move _4 as *const i8 (Misc); + n[48]: copy n[47] => _1 @ bb0[0]: fn printf; _2 = printf(move _3, move _7); + n[49]: copy n[0] => _8 @ bb2[12]: fn inter_function_analysis; _8 = &raw const (*_9); + n[50]: copy n[49] => _7 @ bb2[13]: fn inter_function_analysis; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); + n[51]: copy n[50] => _6 @ bb2[15]: fn inter_function_analysis; _6 = move _7 as *const i8 (Misc); + n[52]: copy n[51] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); + n[53]: copy n[0] => _10 @ bb2[19]: fn invalid; _10 = &raw const (*_11); + n[54]: copy n[53] => _9 @ bb2[20]: fn invalid; _9 = move _10 as *const u8 (Pointer(ArrayToPointer)); + n[55]: copy n[54] => _8 @ bb2[22]: fn invalid; _8 = move _9 as *const i8 (Misc); + n[56]: copy n[55] => _1 @ bb0[0]: fn printf; _7 = printf(move _8, move _12); + n[57]: copy n[0] => _16 @ bb3[10]: fn invalid; _16 = &raw const (*_17); + n[58]: copy n[57] => _15 @ bb3[11]: fn invalid; _15 = move _16 as *const u8 (Pointer(ArrayToPointer)); + n[59]: copy n[58] => _14 @ bb3[13]: fn invalid; _14 = move _15 as *const i8 (Misc); + n[60]: copy n[59] => _1 @ bb0[0]: fn printf; _13 = printf(move _14, move _18); } 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); +g is_null=false { + 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 is_null=false { + n[0]: sized(4) _ => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [] -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); +g is_null=false { + 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 is_null=false { + n[0]: sized(4) _ => _61 @ bb29[5]: fn exercise_allocator; _61 = const b"%i\n\x00"; } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [] + +g is_null=false { + 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 is_null=false { + n[0]: sized(4) _ => _94 @ bb49[5]: fn exercise_allocator; _94 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + 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, 1, 0] + +g is_null=false { + n[0]: sized(4) _ => _9 @ bb2[11]: fn simple_analysis; _9 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + 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, 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); -} -nodes_that_need_write = [4, 3, 2, 1, 0] - -g { +g is_null=false { + n[0]: sized(4) _ => _6 @ bb0[5]: fn analysis2_helper; _6 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + 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, 2, 1, 0] + +g is_null=false { + n[0]: sized(4) _ => _9 @ bb2[11]: fn inter_function_analysis; _9 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { 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); } 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[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[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[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[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); -} -nodes_that_need_write = [14, 13, 9, 8, 5, 4, 1, 0] - -g { +g is_null=false { + n[0]: sized(8) _ => _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]: addr.load n[0] => _ @ bb6[6]: fn main_0; _12 = (*_13); + n[3]: addr.store n[0] => _ @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); + n[4]: addr.load n[0] => _ @ bb3[5]: fn no_owner; _11 = (*_12); + n[5]: addr.store n[0] => _ @ bb2[10]: fn invalid; (*_6) = move _5; + n[6]: addr.load n[0] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[7]: addr.store n[0] => _ @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); +} +nodes_that_need_write = [7, 5, 3, 1, 0] + +g is_null=false { + n[0]: sized(8) _ => _13 @ bb6[5]: fn main_0; _13 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { 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); +g is_null=false { + n[0]: sized(8) _ => _5 @ bb2[2]: fn no_owner; _5 = const {alloc8: *mut *mut pointers::S}; } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [] -g { +g is_null=false { + n[0]: sized(8) _ => _12 @ bb3[4]: fn no_owner; _12 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { + 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[0] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[9]: project[0]@0 n[0] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[10]: addr.load n[0] => _ @ 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, 1, 0] + +g is_null=false { + n[0]: sized(8) _ => _6 @ bb2[9]: fn invalid; _6 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { + n[0]: sized(4) _ => _11 @ bb2[18]: fn invalid; _11 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + n[0]: sized(4) _ => _17 @ bb3[9]: fn invalid; _17 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + n[0]: sized(8) _ => _19 @ bb3[17]: fn invalid; _19 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { + n[0]: sized(8) _ => _20 @ bb4[6]: fn invalid; _20 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { n[0]: &_1 _ => _ @ bb0[2]: fn testing; _8 = &raw mut _1; n[1]: addr.store n[0] => _ @ bb0[1]: fn testing; _1 = const 10_i32; n[2]: copy n[0] => _4 @ bb0[9]: fn testing; _4 = &mut (*_8); @@ -399,7 +463,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_3 _ => _ @ bb0[11]: fn testing; _9 = &raw mut _3; n[1]: addr.store n[0] => _ @ bb0[10]: fn testing; _3 = &raw mut (*_4); n[2]: copy n[0] => _5 @ bb0[15]: fn testing; _5 = &mut (*_9); @@ -407,53 +471,53 @@ 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); +g is_null=false { + 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); -} -nodes_that_need_write = [4, 3, 2, 1, 0] - -g { +g is_null=false { + 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[0] => _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[0] => _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, 2, 1, 0] + +g is_null=false { n[0]: &_13 _ => _ @ bb4[14]: fn simple1; _22 = &raw mut _13; n[1]: addr.store n[0] => _ @ bb4[13]: fn simple1; _13 = _11; n[2]: copy n[0] => _14 @ bb4[17]: fn simple1; _14 = &raw const (*_22); } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: alloc _ => _2 @ bb1[2]: fn lighttpd_test; _2 = malloc(move _3); 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[0] => _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[0] => _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,128 +525,128 @@ 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, 7, 6, 5, 4, 0] + +g is_null=false { + 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[0] => _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[0] => _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[0] => _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); +g is_null=false { + 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[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[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[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] - -g { +g is_null=false { + 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]: 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]: 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]: 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, 8, 7, 6, 3, 1, 0] + +g is_null=false { + 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[0] => _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[0] => _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 is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_malloc_free; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_malloc_free; _5 = _1; n[2]: free n[1] => _4 @ bb2[5]: fn test_malloc_free; _4 = free(move _5); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _2 @ bb1[2]: fn test_malloc_free_cast; _2 = malloc(move _3); n[1]: copy n[0] => _1 @ bb2[1]: fn test_malloc_free_cast; _1 = move _2 as *mut pointers::S (Misc); n[2]: copy n[1] => _7 @ bb2[7]: fn test_malloc_free_cast; _7 = _1; @@ -591,7 +655,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_arg; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_arg; _5 = _1; n[2]: copy n[1] => _1 @ bb0[0]: fn foo; _4 = foo(move _5); @@ -602,7 +666,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_arg_rec; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_arg_rec; _5 = _1; n[2]: copy n[1] => _2 @ bb0[0]: fn foo_rec; _4 = foo_rec(const 3_i32, move _5); @@ -628,7 +692,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb0[2]: fn test_shared_ref; _7 = &raw mut _1; n[1]: addr.store n[0] => _ @ bb0[1]: fn test_shared_ref; _1 = const 2_u8; n[2]: copy n[0] => _2 @ bb0[5]: fn test_shared_ref; _2 = &(*_7); @@ -641,7 +705,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb0[2]: fn test_unique_ref; _8 = &raw mut _1; n[1]: addr.store n[0] => _ @ bb0[1]: fn test_unique_ref; _1 = const 10_i32; n[2]: copy n[0] => _4 @ bb0[9]: fn test_unique_ref; _4 = &mut (*_8); @@ -652,7 +716,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_3 _ => _ @ bb0[11]: fn test_unique_ref; _9 = &raw mut _3; n[1]: addr.store n[0] => _ @ bb0[10]: fn test_unique_ref; _3 = &raw mut (*_4); n[2]: copy n[0] => _5 @ bb0[15]: fn test_unique_ref; _5 = &mut (*_9); @@ -660,14 +724,14 @@ g { } nodes_that_need_write = [3, 2, 1, 0] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_realloc_reassign; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_realloc_reassign; _5 = _1; n[2]: free n[1] => _4 @ bb4[2]: fn test_realloc_reassign; _4 = realloc(move _5, move _6); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _4 @ bb4[2]: fn test_realloc_reassign; _4 = realloc(move _5, move _6); n[1]: copy n[0] => _1 @ bb5[2]: fn test_realloc_reassign; _1 = move _4; n[2]: copy n[1] => _11 @ bb5[6]: fn test_realloc_reassign; _11 = _1; @@ -675,21 +739,21 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_realloc_fresh; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_realloc_fresh; _5 = _1; n[2]: free n[1] => _4 @ bb3[2]: fn test_realloc_fresh; _4 = realloc(move _5, move _6); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _4 @ bb3[2]: fn test_realloc_fresh; _4 = realloc(move _5, move _6); n[1]: copy n[0] => _9 @ bb4[5]: fn test_realloc_fresh; _9 = _4; n[2]: free n[1] => _8 @ bb4[6]: fn test_realloc_fresh; _8 = free(move _9); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _2 @ bb1[2]: fn test_load_addr; _2 = calloc(const 1_u64, move _3); n[1]: copy n[0] => _1 @ bb2[1]: fn test_load_addr; _1 = move _2 as *mut pointers::S (Misc); n[2]: addr.load n[1] => _ @ bb2[5]: fn test_load_addr; _5 = (*_1); @@ -699,7 +763,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_overwrite; _1 = malloc(move _2); n[1]: copy n[0] => _4 @ bb2[3]: fn test_overwrite; _4 = _1; n[2]: copy n[1] => _12 @ bb5[4]: fn test_overwrite; _12 = _4; @@ -707,7 +771,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _5 @ bb3[2]: fn test_overwrite; _5 = malloc(move _6); n[1]: copy n[0] => _8 @ bb4[3]: fn test_overwrite; _8 = _5; n[2]: copy n[1] => _1 @ bb4[4]: fn test_overwrite; _1 = move _8; @@ -716,104 +780,102 @@ 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); +g is_null=false { + 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] - -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); -} -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); +g is_null=false { + 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 _ => _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); -} -nodes_that_need_write = [7, 6, 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); +g is_null=false { + 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 = [5, 4, 1, 0] +nodes_that_need_write = [3, 1, 0] -g { +g is_null=false { + 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[3, 3]@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[3, 3]@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 = [5, 1, 0] + +g is_null=false { + 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, 1, 0] + +g is_null=false { 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); } nodes_that_need_write = [] -g { +g is_null=false { 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 = [] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb2[0]: fn test_load_value; _7 = &raw mut _1; n[1]: copy n[0] => _4 @ bb2[4]: fn test_load_value; _4 = &raw const (*_7); n[2]: addr.load n[1] => _ @ bb2[8]: fn test_load_value; _6 = (*_4); } nodes_that_need_write = [] -g { +g is_null=false { 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 = [] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb2[0]: fn test_store_value; _9 = &raw mut _1; n[1]: addr.load n[0] => _ @ bb2[4]: fn test_store_value; _4 = (*_9); n[2]: copy n[0] => _5 @ bb2[7]: fn test_store_value; _5 = &raw mut (*_9); @@ -822,44 +884,44 @@ 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); -} -nodes_that_need_write = [6, 5, 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); +g is_null=false { + 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, 1, 0] + +g is_null=false { + 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 { +g is_null=false { 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 = [] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb2[0]: fn test_load_value_store_value; _8 = &raw mut _1; n[1]: copy n[0] => _4 @ bb2[4]: fn test_load_value_store_value; _4 = &raw mut (*_8); n[2]: addr.load n[1] => _ @ bb2[7]: fn test_load_value_store_value; _5 = (*_4); @@ -868,10 +930,10 @@ g { } nodes_that_need_write = [3, 1, 0] -g { - n[0]: &_40 _ => _ @ bb32[4]: fn main_0; _59 = &raw mut _40; +g is_null=false { + n[0]: &_40 _ => _ @ bb32[4]: fn main_0; _58 = &raw mut _40; n[1]: addr.store n[0] => _ @ bb32[3]: fn main_0; _40 = [const 2_i32, const 5_i32, const 3_i32, const 1_i32, const 6_i32]; - n[2]: copy n[0] => _39 @ bb32[5]: fn main_0; _39 = &mut (*_59); + n[2]: copy n[0] => _39 @ bb32[5]: fn main_0; _39 = &mut (*_58); n[3]: copy n[2] => _45 @ bb32[12]: fn main_0; _45 = &(*_39); n[4]: copy n[3] => _44 @ bb32[13]: fn main_0; _44 = move _45 as &[i32] (Pointer(Unsize)); n[5]: copy n[4] => _1 @ bb0[0]: fn len; _43 = len(move _44); @@ -950,20 +1012,7 @@ 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; -} -nodes_that_need_write = [8, 7, 6, 2, 1, 0] - -g { +g is_null=false { n[0]: &_1 _ => _ @ bb0[2]: fn test_addr_taken; _10 = &raw mut _1; n[1]: addr.store n[0] => _ @ bb0[1]: fn test_addr_taken; _1 = const 2_i32; n[2]: addr.load n[0] => _ @ bb0[6]: fn test_addr_taken; _3 = (*_10); @@ -972,15 +1021,15 @@ 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); +g is_null=false { + 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 { +g is_null=false { n[0]: &_3 _ => _ @ bb2[2]: fn test_addr_taken_loop; _20 = &raw mut _3; n[1]: addr.store n[0] => _ @ bb2[1]: fn test_addr_taken_loop; _3 = const 2_i32; n[2]: copy n[0] => _4 @ bb5[0]: fn test_addr_taken_loop; _4 = &(*_20); @@ -995,7 +1044,7 @@ g { } nodes_that_need_write = [9, 8, 5, 4, 1, 0] -g { +g is_null=false { n[0]: &_2 _ => _ @ bb1[1]: fn test_addr_taken_cond; _6 = &raw mut _2; n[1]: addr.store n[0] => _ @ bb1[0]: fn test_addr_taken_cond; _2 = const 1_i32; n[2]: copy n[0] => _4 @ bb4[3]: fn test_addr_taken_cond; _4 = &(*_6); @@ -1003,7 +1052,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_2 _ => _ @ bb3[1]: fn test_addr_taken_cond; _6 = &raw mut _2; n[1]: addr.store n[0] => _ @ bb3[0]: fn test_addr_taken_cond; _2 = const 2_i32; n[2]: copy n[0] => _4 @ bb4[3]: fn test_addr_taken_cond; _4 = &(*_6); @@ -1011,7 +1060,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_2 _ => _ @ bb1[1]: fn test_addr_taken_init_cond; _8 = &raw mut _2; n[1]: addr.store n[0] => _ @ bb1[0]: fn test_addr_taken_init_cond; _2 = const 1_i32; n[2]: copy n[0] => _6 @ bb1[3]: fn test_addr_taken_init_cond; _6 = &(*_8); @@ -1022,13 +1071,13 @@ g { } nodes_that_need_write = [5, 4, 1, 0] -g { +g is_null=false { n[0]: &_2 _ => _ @ bb4[3]: fn test_addr_taken_init_cond; _8 = &raw mut _2; n[1]: addr.store n[0] => _ @ bb4[2]: fn test_addr_taken_init_cond; _2 = const 2_i32; n[2]: addr.load n[0] => _ @ bb4[5]: fn test_addr_taken_init_cond; _7 = (*_8); } nodes_that_need_write = [1, 0] -num_graphs = 67 -num_nodes = 759 +num_graphs = 80 +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..09e34b8a04 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,35 +1,47 @@ --- source: pdg/src/main.rs +assertion_line: 384 expression: pdg --- -g { +g is_null=false { n[0]: &_1 _ => _ @ bb3[0]: fn main; _22 = &raw mut _1; n[1]: copy n[0] => _11 @ bb3[10]: fn main; _11 = &(*_22); n[2]: copy n[1] => _1 @ bb0[0]: fn deref; _10 = deref(move _11); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: copy _ => _10 @ bb3[11]: fn main; _10 = deref(move _11); n[1]: copy n[0] => _9 @ bb4[0]: fn main; _9 = &(*_10); n[2]: copy n[1] => _1 @ bb0[0]: fn iter; _8 = iter(move _9); } 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); +g is_null=true { + 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 n[0] => _17 @ bb4[29]: fn simple; _17 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[3]: copy n[0] => _23 @ bb5[4]: fn simple; _23 = null_mut(); + n[4]: copy n[3] => _2 @ bb0[0]: fn recur; _22 = recur(const 3_i32, move _23); + n[5]: copy n[4] => _16 @ bb14[9]: fn recur; _16 = _2; + n[6]: copy n[5] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _16); + n[7]: copy n[6] => _16 @ bb14[9]: fn recur; _16 = _2; + n[8]: copy n[7] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _16); + n[9]: copy n[8] => _16 @ bb14[9]: fn recur; _16 = _2; + n[10]: copy n[9] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _16); + n[11]: copy n[10] => _9 @ bb1[3]: fn recur; _9 = _2; + n[12]: copy n[11] => _1 @ bb0[0]: fn is_null; _8 = is_null(move _9); + n[13]: copy n[10] => _17 @ bb15[4]: fn recur; _17 = _2; + n[14]: copy n[10] => _17 @ bb15[4]: fn recur; _17 = _2; + n[15]: copy n[10] => _17 @ bb15[4]: fn recur; _17 = _2; + n[16]: value.store n[0] => _20.* @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); + n[17]: value.store n[0] => _17.* @ bb8[4]: fn fdevent_unregister; (*_17) = const 0_usize as *mut pointers::fdnode_st (PointerFromExposedAddress); + n[18]: int_to_ptr n[0] => _50 @ bb35[3]: fn main_0; _50 = const 0_usize as *const pointers::S (PointerFromExposedAddress); + n[19]: 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 = [] -g { +g is_null=false { n[0]: &_5 _ => _ @ bb10[0]: fn main; _23 = &raw mut _5; n[1]: copy n[0] => _19 @ bb10[9]: fn main; _19 = &(*_23); n[2]: copy n[1] => _1 @ bb0[0]: fn len; _18 = len(move _19); @@ -37,358 +49,410 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: copy _ => _20 @ bb11[8]: fn main; _20 = as_mut_ptr(move _21); n[1]: copy n[0] => _2 @ bb0[0]: fn main_0; _15 = main_0(move _16, move _20); } 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); +g is_null=false { + 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] => _26 @ bb7[5]: fn simple; _26 = _5; + n[5]: copy n[4] => _25 @ bb7[6]: fn simple; _25 = move _26 as *mut libc::c_void (Misc); + n[6]: free n[5] => _24 @ bb7[8]: fn simple; _24 = free(move _25); } 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); +g is_null=false { + 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] => _16 @ bb14[9]: fn recur; _16 = _2; + n[26]: copy n[25] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _16); + n[27]: copy n[26] => _16 @ bb14[9]: fn recur; _16 = _2; + n[28]: copy n[27] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _16); + n[29]: copy n[28] => _16 @ bb14[9]: fn recur; _16 = _2; + n[30]: copy n[29] => _2 @ bb0[0]: fn recur; _13 = recur(move _14, move _16); + n[31]: copy n[30] => _9 @ bb1[3]: fn recur; _9 = _2; + n[32]: copy n[31] => _1 @ bb0[0]: fn is_null; _8 = is_null(move _9); + n[33]: copy n[30] => _12 @ bb9[4]: fn recur; _12 = _2; + n[34]: copy n[33] => _11 @ bb9[5]: fn recur; _11 = move _12 as *mut libc::c_void (Misc); + n[35]: free n[34] => _0 @ bb9[7]: fn recur; _0 = free(move _11); +} +nodes_that_need_write = [22, 20, 17, 11, 9, 5, 3, 2, 1, 0] + +g is_null=false { + n[0]: copy _ => _17 @ bb15[4]: fn recur; _17 = _2; + n[1]: copy n[0] => _17 @ bb15[4]: fn recur; _17 = _2; + n[2]: copy n[0] => _17 @ bb15[4]: fn recur; _17 = _2; } 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); +g is_null=false { + 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 = [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"; - n[1]: copy n[0] => _8 @ bb2[12]: fn exercise_allocator; _8 = &raw const (*_9); - 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[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[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[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[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[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[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[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[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[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[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[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[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[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[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); - n[74]: copy n[73] => _1 @ bb0[0]: fn printf; _13 = printf(move _14, move _18); +g is_null=false { + n[0]: sized(4) _ => _9 @ bb2[11]: fn exercise_allocator; _9 = const b"%i\n\x00"; + n[1]: copy n[0] => _8 @ bb2[12]: fn exercise_allocator; _8 = &raw const (*_9); + 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 n[0] => _30 @ bb11[6]: fn exercise_allocator; _30 = &raw const (*_31); + n[6]: copy n[5] => _29 @ bb11[7]: fn exercise_allocator; _29 = move _30 as *const u8 (Pointer(ArrayToPointer)); + n[7]: copy n[6] => _28 @ bb11[9]: fn exercise_allocator; _28 = move _29 as *const i8 (Misc); + n[8]: copy n[7] => _1 @ bb0[0]: fn printf; _27 = printf(move _28, move _32); + n[9]: copy n[0] => _30 @ bb11[6]: fn exercise_allocator; _30 = &raw const (*_31); + n[10]: copy n[9] => _29 @ bb11[7]: fn exercise_allocator; _29 = move _30 as *const u8 (Pointer(ArrayToPointer)); + n[11]: copy n[10] => _28 @ bb11[9]: fn exercise_allocator; _28 = move _29 as *const i8 (Misc); + n[12]: copy n[11] => _1 @ bb0[0]: fn printf; _27 = printf(move _28, move _32); + n[13]: copy n[0] => _59 @ bb28[6]: fn exercise_allocator; _59 = &raw const (*_60); + n[14]: copy n[13] => _58 @ bb28[7]: fn exercise_allocator; _58 = move _59 as *const u8 (Pointer(ArrayToPointer)); + n[15]: copy n[14] => _57 @ bb28[9]: fn exercise_allocator; _57 = move _58 as *const i8 (Misc); + n[16]: copy n[15] => _1 @ bb0[0]: fn printf; _56 = printf(move _57, move _61); + n[17]: copy n[0] => _59 @ bb28[6]: fn exercise_allocator; _59 = &raw const (*_60); + n[18]: copy n[17] => _58 @ bb28[7]: fn exercise_allocator; _58 = move _59 as *const u8 (Pointer(ArrayToPointer)); + n[19]: copy n[18] => _57 @ bb28[9]: fn exercise_allocator; _57 = move _58 as *const i8 (Misc); + n[20]: copy n[19] => _1 @ bb0[0]: fn printf; _56 = printf(move _57, move _61); + n[21]: copy n[0] => _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 n[0] => _91 @ bb47[6]: fn exercise_allocator; _91 = &raw const (*_92); + n[26]: copy n[25] => _90 @ bb47[7]: fn exercise_allocator; _90 = move _91 as *const u8 (Pointer(ArrayToPointer)); + n[27]: copy n[26] => _89 @ bb47[9]: fn exercise_allocator; _89 = move _90 as *const i8 (Misc); + n[28]: copy n[27] => _1 @ bb0[0]: fn printf; _88 = printf(move _89, move _93); + n[29]: copy n[0] => _91 @ bb47[6]: fn exercise_allocator; _91 = &raw const (*_92); + n[30]: copy n[29] => _90 @ bb47[7]: fn exercise_allocator; _90 = move _91 as *const u8 (Pointer(ArrayToPointer)); + n[31]: copy n[30] => _89 @ bb47[9]: fn exercise_allocator; _89 = move _90 as *const i8 (Misc); + n[32]: copy n[31] => _1 @ bb0[0]: fn printf; _88 = printf(move _89, move _93); + n[33]: copy n[0] => _91 @ bb47[6]: fn exercise_allocator; _91 = &raw const (*_92); + n[34]: copy n[33] => _90 @ bb47[7]: fn exercise_allocator; _90 = move _91 as *const u8 (Pointer(ArrayToPointer)); + n[35]: copy n[34] => _89 @ bb47[9]: fn exercise_allocator; _89 = move _90 as *const i8 (Misc); + n[36]: copy n[35] => _1 @ bb0[0]: fn printf; _88 = printf(move _89, move _93); + n[37]: copy n[0] => _91 @ bb47[6]: fn exercise_allocator; _91 = &raw const (*_92); + n[38]: copy n[37] => _90 @ bb47[7]: fn exercise_allocator; _90 = move _91 as *const u8 (Pointer(ArrayToPointer)); + n[39]: copy n[38] => _89 @ bb47[9]: fn exercise_allocator; _89 = move _90 as *const i8 (Misc); + n[40]: copy n[39] => _1 @ bb0[0]: fn printf; _88 = printf(move _89, move _93); + n[41]: copy n[0] => _8 @ bb2[12]: fn simple_analysis; _8 = &raw const (*_9); + n[42]: copy n[41] => _7 @ bb2[13]: fn simple_analysis; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); + n[43]: copy n[42] => _6 @ bb2[15]: fn simple_analysis; _6 = move _7 as *const i8 (Misc); + n[44]: copy n[43] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); + n[45]: copy n[43] => _5 @ bb0[6]: fn analysis2_helper; _5 = &raw const (*_6); + n[46]: copy n[45] => _4 @ bb0[7]: fn analysis2_helper; _4 = move _5 as *const u8 (Pointer(ArrayToPointer)); + n[47]: copy n[46] => _3 @ bb0[9]: fn analysis2_helper; _3 = move _4 as *const i8 (Misc); + n[48]: copy n[47] => _1 @ bb0[0]: fn printf; _2 = printf(move _3, move _7); + n[49]: copy n[0] => _8 @ bb2[12]: fn inter_function_analysis; _8 = &raw const (*_9); + n[50]: copy n[49] => _7 @ bb2[13]: fn inter_function_analysis; _7 = move _8 as *const u8 (Pointer(ArrayToPointer)); + n[51]: copy n[50] => _6 @ bb2[15]: fn inter_function_analysis; _6 = move _7 as *const i8 (Misc); + n[52]: copy n[51] => _1 @ bb0[0]: fn printf; _5 = printf(move _6, move _10); + n[53]: copy n[0] => _10 @ bb2[19]: fn invalid; _10 = &raw const (*_11); + n[54]: copy n[53] => _9 @ bb2[20]: fn invalid; _9 = move _10 as *const u8 (Pointer(ArrayToPointer)); + n[55]: copy n[54] => _8 @ bb2[22]: fn invalid; _8 = move _9 as *const i8 (Misc); + n[56]: copy n[55] => _1 @ bb0[0]: fn printf; _7 = printf(move _8, move _12); + n[57]: copy n[0] => _16 @ bb3[10]: fn invalid; _16 = &raw const (*_17); + n[58]: copy n[57] => _15 @ bb3[11]: fn invalid; _15 = move _16 as *const u8 (Pointer(ArrayToPointer)); + n[59]: copy n[58] => _14 @ bb3[13]: fn invalid; _14 = move _15 as *const i8 (Misc); + n[60]: copy n[59] => _1 @ bb0[0]: fn printf; _13 = printf(move _14, move _18); } 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); +g is_null=false { + 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 is_null=false { + n[0]: sized(4) _ => _31 @ bb11[5]: fn exercise_allocator; _31 = const b"%i\n\x00"; } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [] -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); +g is_null=false { + 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 is_null=false { + n[0]: sized(4) _ => _60 @ bb28[5]: fn exercise_allocator; _60 = const b"%i\n\x00"; } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [] + +g is_null=false { + 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 is_null=false { + n[0]: sized(4) _ => _92 @ bb47[5]: fn exercise_allocator; _92 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + 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, 1, 0] + +g is_null=false { + n[0]: sized(4) _ => _9 @ bb2[11]: fn simple_analysis; _9 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + 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, 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); -} -nodes_that_need_write = [4, 3, 2, 1, 0] - -g { +g is_null=false { + n[0]: sized(4) _ => _6 @ bb0[5]: fn analysis2_helper; _6 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + 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, 2, 1, 0] + +g is_null=false { + n[0]: sized(4) _ => _9 @ bb2[11]: fn inter_function_analysis; _9 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { 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); } 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[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[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[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[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); -} -nodes_that_need_write = [14, 13, 9, 8, 5, 4, 1, 0] - -g { +g is_null=false { + n[0]: sized(8) _ => _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]: addr.load n[0] => _ @ bb6[6]: fn main_0; _12 = (*_13); + n[3]: addr.store n[0] => _ @ bb2[3]: fn no_owner; (*_5) = move _2 as *mut pointers::S (Misc); + n[4]: addr.load n[0] => _ @ bb3[5]: fn no_owner; _11 = (*_12); + n[5]: addr.store n[0] => _ @ bb2[10]: fn invalid; (*_6) = move _5; + n[6]: addr.load n[0] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[7]: addr.store n[0] => _ @ bb4[7]: fn invalid; (*_20) = const 0_usize as *mut pointers::S (PointerFromExposedAddress); +} +nodes_that_need_write = [7, 5, 3, 1, 0] + +g is_null=false { + n[0]: sized(8) _ => _13 @ bb6[5]: fn main_0; _13 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { 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); +g is_null=false { + n[0]: sized(8) _ => _5 @ bb2[2]: fn no_owner; _5 = const {alloc8: *mut *mut pointers::S}; } -nodes_that_need_write = [3, 2, 1, 0] +nodes_that_need_write = [] -g { +g is_null=false { + n[0]: sized(8) _ => _12 @ bb3[4]: fn no_owner; _12 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { + 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[0] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[9]: project[0]@0 n[0] => _ @ bb3[18]: fn invalid; _18 = ((*(*_19)).0: i32); + n[10]: addr.load n[0] => _ @ 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, 1, 0] + +g is_null=false { + n[0]: sized(8) _ => _6 @ bb2[9]: fn invalid; _6 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { + n[0]: sized(4) _ => _11 @ bb2[18]: fn invalid; _11 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + n[0]: sized(4) _ => _17 @ bb3[9]: fn invalid; _17 = const b"%i\n\x00"; +} +nodes_that_need_write = [] + +g is_null=false { + n[0]: sized(8) _ => _19 @ bb3[17]: fn invalid; _19 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { + n[0]: sized(8) _ => _20 @ bb4[6]: fn invalid; _20 = const {alloc8: *mut *mut pointers::S}; +} +nodes_that_need_write = [] + +g is_null=false { n[0]: &_1 _ => _ @ bb0[2]: fn testing; _8 = &raw mut _1; n[1]: addr.store n[0] => _ @ bb0[1]: fn testing; _1 = const 10_i32; n[2]: copy n[0] => _4 @ bb0[9]: fn testing; _4 = &mut (*_8); @@ -399,7 +463,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_3 _ => _ @ bb0[11]: fn testing; _9 = &raw mut _3; n[1]: addr.store n[0] => _ @ bb0[10]: fn testing; _3 = &raw mut (*_4); n[2]: copy n[0] => _5 @ bb0[15]: fn testing; _5 = &mut (*_9); @@ -407,53 +471,53 @@ 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); +g is_null=false { + 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); -} -nodes_that_need_write = [4, 3, 2, 1, 0] - -g { +g is_null=false { + 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[0] => _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[0] => _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, 2, 1, 0] + +g is_null=false { n[0]: &_13 _ => _ @ bb4[14]: fn simple1; _22 = &raw mut _13; n[1]: addr.store n[0] => _ @ bb4[13]: fn simple1; _13 = _11; n[2]: copy n[0] => _14 @ bb4[17]: fn simple1; _14 = &raw const (*_22); } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: alloc _ => _2 @ bb1[2]: fn lighttpd_test; _2 = malloc(move _3); 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[0] => _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[0] => _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,128 +525,128 @@ 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, 7, 6, 5, 4, 0] + +g is_null=false { + 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[0] => _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[0] => _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[0] => _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); +g is_null=false { + 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[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[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[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] - -g { +g is_null=false { + 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]: 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]: 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]: 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, 8, 7, 6, 3, 1, 0] + +g is_null=false { + 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[0] => _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[0] => _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 is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_malloc_free; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_malloc_free; _5 = _1; n[2]: free n[1] => _4 @ bb2[5]: fn test_malloc_free; _4 = free(move _5); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _2 @ bb1[2]: fn test_malloc_free_cast; _2 = malloc(move _3); n[1]: copy n[0] => _1 @ bb2[1]: fn test_malloc_free_cast; _1 = move _2 as *mut pointers::S (Misc); n[2]: copy n[1] => _7 @ bb2[7]: fn test_malloc_free_cast; _7 = _1; @@ -591,7 +655,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_arg; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_arg; _5 = _1; n[2]: copy n[1] => _1 @ bb0[0]: fn foo; _4 = foo(move _5); @@ -602,7 +666,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_arg_rec; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_arg_rec; _5 = _1; n[2]: copy n[1] => _2 @ bb0[0]: fn foo_rec; _4 = foo_rec(const 3_i32, move _5); @@ -628,7 +692,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb0[2]: fn test_shared_ref; _7 = &raw mut _1; n[1]: addr.store n[0] => _ @ bb0[1]: fn test_shared_ref; _1 = const 2_u8; n[2]: copy n[0] => _2 @ bb0[5]: fn test_shared_ref; _2 = &(*_7); @@ -641,7 +705,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb0[2]: fn test_unique_ref; _8 = &raw mut _1; n[1]: addr.store n[0] => _ @ bb0[1]: fn test_unique_ref; _1 = const 10_i32; n[2]: copy n[0] => _4 @ bb0[9]: fn test_unique_ref; _4 = &mut (*_8); @@ -652,7 +716,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_3 _ => _ @ bb0[11]: fn test_unique_ref; _9 = &raw mut _3; n[1]: addr.store n[0] => _ @ bb0[10]: fn test_unique_ref; _3 = &raw mut (*_4); n[2]: copy n[0] => _5 @ bb0[15]: fn test_unique_ref; _5 = &mut (*_9); @@ -660,14 +724,14 @@ g { } nodes_that_need_write = [3, 2, 1, 0] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_realloc_reassign; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_realloc_reassign; _5 = _1; n[2]: free n[1] => _4 @ bb3[4]: fn test_realloc_reassign; _4 = realloc(move _5, move _6); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _4 @ bb3[4]: fn test_realloc_reassign; _4 = realloc(move _5, move _6); n[1]: copy n[0] => _1 @ bb4[2]: fn test_realloc_reassign; _1 = move _4; n[2]: copy n[1] => _10 @ bb4[6]: fn test_realloc_reassign; _10 = _1; @@ -675,21 +739,21 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_realloc_fresh; _1 = malloc(move _2); n[1]: copy n[0] => _5 @ bb2[4]: fn test_realloc_fresh; _5 = _1; n[2]: free n[1] => _4 @ bb3[2]: fn test_realloc_fresh; _4 = realloc(move _5, move _6); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _4 @ bb3[2]: fn test_realloc_fresh; _4 = realloc(move _5, move _6); n[1]: copy n[0] => _9 @ bb4[5]: fn test_realloc_fresh; _9 = _4; n[2]: free n[1] => _8 @ bb4[6]: fn test_realloc_fresh; _8 = free(move _9); } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _2 @ bb1[2]: fn test_load_addr; _2 = calloc(const 1_u64, move _3); n[1]: copy n[0] => _1 @ bb2[1]: fn test_load_addr; _1 = move _2 as *mut pointers::S (Misc); n[2]: addr.load n[1] => _ @ bb2[5]: fn test_load_addr; _5 = (*_1); @@ -699,7 +763,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _1 @ bb1[2]: fn test_overwrite; _1 = malloc(move _2); n[1]: copy n[0] => _4 @ bb2[3]: fn test_overwrite; _4 = _1; n[2]: copy n[1] => _12 @ bb5[4]: fn test_overwrite; _12 = _4; @@ -707,7 +771,7 @@ g { } nodes_that_need_write = [] -g { +g is_null=false { n[0]: alloc _ => _5 @ bb3[2]: fn test_overwrite; _5 = malloc(move _6); n[1]: copy n[0] => _8 @ bb4[3]: fn test_overwrite; _8 = _5; n[2]: copy n[1] => _1 @ bb4[4]: fn test_overwrite; _1 = move _8; @@ -716,104 +780,102 @@ 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); +g is_null=false { + 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] - -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); -} -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); +g is_null=false { + 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 _ => _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); -} -nodes_that_need_write = [7, 6, 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); +g is_null=false { + 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 = [5, 4, 1, 0] +nodes_that_need_write = [3, 1, 0] -g { +g is_null=false { + 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[3, 3]@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[3, 3]@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 = [5, 1, 0] + +g is_null=false { + 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, 1, 0] + +g is_null=false { 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); } nodes_that_need_write = [] -g { +g is_null=false { 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 = [] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb2[0]: fn test_load_value; _7 = &raw mut _1; n[1]: copy n[0] => _4 @ bb2[4]: fn test_load_value; _4 = &raw const (*_7); n[2]: addr.load n[1] => _ @ bb2[8]: fn test_load_value; _6 = (*_4); } nodes_that_need_write = [] -g { +g is_null=false { 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 = [] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb2[0]: fn test_store_value; _9 = &raw mut _1; n[1]: addr.load n[0] => _ @ bb2[4]: fn test_store_value; _4 = (*_9); n[2]: copy n[0] => _5 @ bb2[7]: fn test_store_value; _5 = &raw mut (*_9); @@ -822,44 +884,44 @@ 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); -} -nodes_that_need_write = [6, 5, 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); +g is_null=false { + 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, 1, 0] + +g is_null=false { + 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 { +g is_null=false { 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 = [] -g { +g is_null=false { n[0]: &_1 _ => _ @ bb2[0]: fn test_load_value_store_value; _8 = &raw mut _1; n[1]: copy n[0] => _4 @ bb2[4]: fn test_load_value_store_value; _4 = &raw mut (*_8); n[2]: addr.load n[1] => _ @ bb2[7]: fn test_load_value_store_value; _5 = (*_4); @@ -868,10 +930,10 @@ g { } nodes_that_need_write = [3, 1, 0] -g { - n[0]: &_40 _ => _ @ bb32[4]: fn main_0; _59 = &raw mut _40; +g is_null=false { + n[0]: &_40 _ => _ @ bb32[4]: fn main_0; _58 = &raw mut _40; n[1]: addr.store n[0] => _ @ bb32[3]: fn main_0; _40 = [const 2_i32, const 5_i32, const 3_i32, const 1_i32, const 6_i32]; - n[2]: copy n[0] => _39 @ bb32[5]: fn main_0; _39 = &mut (*_59); + n[2]: copy n[0] => _39 @ bb32[5]: fn main_0; _39 = &mut (*_58); n[3]: copy n[2] => _45 @ bb32[12]: fn main_0; _45 = &(*_39); n[4]: copy n[3] => _44 @ bb32[13]: fn main_0; _44 = move _45 as &[i32] (Pointer(Unsize)); n[5]: copy n[4] => _1 @ bb0[0]: fn len; _43 = len(move _44); @@ -950,20 +1012,7 @@ 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; -} -nodes_that_need_write = [8, 7, 6, 2, 1, 0] - -g { +g is_null=false { n[0]: &_1 _ => _ @ bb0[2]: fn test_addr_taken; _8 = &raw mut _1; n[1]: addr.store n[0] => _ @ bb0[1]: fn test_addr_taken; _1 = const 2_i32; n[2]: addr.load n[0] => _ @ bb0[6]: fn test_addr_taken; _3 = (*_8); @@ -972,15 +1021,15 @@ 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); +g is_null=false { + 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 { +g is_null=false { n[0]: &_3 _ => _ @ bb2[2]: fn test_addr_taken_loop; _19 = &raw mut _3; n[1]: addr.store n[0] => _ @ bb2[1]: fn test_addr_taken_loop; _3 = const 2_i32; n[2]: copy n[0] => _4 @ bb5[0]: fn test_addr_taken_loop; _4 = &(*_19); @@ -995,7 +1044,7 @@ g { } nodes_that_need_write = [9, 8, 5, 4, 1, 0] -g { +g is_null=false { n[0]: &_2 _ => _ @ bb1[1]: fn test_addr_taken_cond; _6 = &raw mut _2; n[1]: addr.store n[0] => _ @ bb1[0]: fn test_addr_taken_cond; _2 = const 1_i32; n[2]: copy n[0] => _4 @ bb4[3]: fn test_addr_taken_cond; _4 = &(*_6); @@ -1003,7 +1052,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_2 _ => _ @ bb3[1]: fn test_addr_taken_cond; _6 = &raw mut _2; n[1]: addr.store n[0] => _ @ bb3[0]: fn test_addr_taken_cond; _2 = const 2_i32; n[2]: copy n[0] => _4 @ bb4[3]: fn test_addr_taken_cond; _4 = &(*_6); @@ -1011,7 +1060,7 @@ g { } nodes_that_need_write = [1, 0] -g { +g is_null=false { n[0]: &_2 _ => _ @ bb1[1]: fn test_addr_taken_init_cond; _8 = &raw mut _2; n[1]: addr.store n[0] => _ @ bb1[0]: fn test_addr_taken_init_cond; _2 = const 1_i32; n[2]: copy n[0] => _6 @ bb1[3]: fn test_addr_taken_init_cond; _6 = &(*_8); @@ -1022,13 +1071,13 @@ g { } nodes_that_need_write = [5, 4, 1, 0] -g { +g is_null=false { n[0]: &_2 _ => _ @ bb4[3]: fn test_addr_taken_init_cond; _8 = &raw mut _2; n[1]: addr.store n[0] => _ @ bb4[2]: fn test_addr_taken_init_cond; _2 = const 2_i32; n[2]: addr.load n[0] => _ @ bb4[5]: fn test_addr_taken_init_cond; _7 = (*_8); } nodes_that_need_write = [1, 0] -num_graphs = 67 -num_nodes = 759 +num_graphs = 80 +num_nodes = 755