diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index fc7d4aa3..a473dc7c 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1,4 +1,3 @@ -use graph::elem::RangeElem; use analyzers::{FunctionVarsBoundAnalyzer, ReportConfig, ReportDisplay}; use graph::{ nodes::{ContractNode, FunctionNode}, @@ -12,7 +11,7 @@ use shared::Search; use ariadne::sources; use clap::{ArgAction, Parser, ValueHint}; -use tracing_subscriber::{Registry, prelude::*}; +use tracing_subscriber::{prelude::*, Registry}; use std::{ collections::{BTreeMap, HashMap}, @@ -111,19 +110,18 @@ pub fn subscriber() { } pub fn tree_subscriber() { - let subscriber = Registry::default().with( - tracing_tree::HierarchicalLayer::default() - .with_indent_lines(true) - .with_indent_amount(2) - .with_thread_names(true) - // .with_thread_ids(true) - // .with_verbose_exit(true) - // .with_verbose_entry(true) - // .with_targets(true) - ) + let subscriber = Registry::default() + .with( + tracing_tree::HierarchicalLayer::default() + .with_indent_lines(true) + .with_indent_amount(2) + .with_thread_names(true), // .with_thread_ids(true) + // .with_verbose_exit(true) + // .with_verbose_entry(true) + // .with_targets(true) + ) .with(tracing_subscriber::filter::EnvFilter::from_default_env()); tracing::subscriber::set_global_default(subscriber).unwrap(); - } fn main() { diff --git a/crates/graph/src/nodes/builtin.rs b/crates/graph/src/nodes/builtin.rs index d0e63896..c9feff60 100644 --- a/crates/graph/src/nodes/builtin.rs +++ b/crates/graph/src/nodes/builtin.rs @@ -46,10 +46,7 @@ impl BuiltInNode { } /// Gets the maximum size version of this builtin, i.e. uint16 -> uint256 - pub fn max_size( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result { + pub fn max_size(&self, analyzer: &mut impl AnalyzerBackend) -> Result { let m = self.underlying(analyzer)?.max_size(); Ok(analyzer.builtin_or_add(m).into()) } @@ -57,7 +54,7 @@ impl BuiltInNode { /// Gets the underlying type of the dynamic builtin backing it. i.e. uint256[] -> uint256 pub fn dynamic_underlying_ty( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { match self.underlying(analyzer)? { Builtin::Array(v_ty) | Builtin::SizedArray(_, v_ty) => { @@ -172,7 +169,7 @@ impl Builtin { /// `mapping (uint => MyType)`, we may not have parsed `MyType`, so we now try to resolve it pub fn unresolved_as_resolved( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { match self { Builtin::Array(n) => Ok(Builtin::Array(n.unresolved_as_resolved(analyzer)?)), @@ -253,7 +250,7 @@ impl Builtin { /// Try to convert from a [`Type`] to a Builtin pub fn try_from_ty( ty: Type, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Option { use Type::*; match ty { diff --git a/crates/graph/src/nodes/concrete.rs b/crates/graph/src/nodes/concrete.rs index 0dd25243..bd1c5ef3 100644 --- a/crates/graph/src/nodes/concrete.rs +++ b/crates/graph/src/nodes/concrete.rs @@ -26,10 +26,7 @@ impl ConcreteNode { } /// Creates a version of this concrete that is max size - pub fn max_size( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result { + pub fn max_size(&self, analyzer: &mut impl AnalyzerBackend) -> Result { let c = self.underlying(analyzer)?.max_size(); Ok(analyzer.add_node(Node::Concrete(c)).into()) } @@ -37,7 +34,7 @@ impl ConcreteNode { /// Gets the internal type of the dynamic that backs this. Panics if this is not a dynamic concrete pub fn dynamic_underlying_ty( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { let builtin = self.underlying(analyzer)?.dynamic_underlying_ty().unwrap(); let bn = analyzer.builtin_or_add(builtin); diff --git a/crates/graph/src/nodes/context/node.rs b/crates/graph/src/nodes/context/node.rs index 1c1f7790..4a6fb6aa 100644 --- a/crates/graph/src/nodes/context/node.rs +++ b/crates/graph/src/nodes/context/node.rs @@ -27,10 +27,7 @@ impl ContextNode { } /// Gets the total context width - pub fn total_width( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result { + pub fn total_width(&self, analyzer: &mut impl AnalyzerBackend) -> Result { self.first_ancestor(analyzer)? .number_of_live_edges(analyzer) } @@ -48,7 +45,7 @@ impl ContextNode { /// Gets a mutable reference to the underlying context in the graph pub fn underlying_mut<'a>( &self, - analyzer: &'a mut (impl GraphBackend + AnalyzerBackend), + analyzer: &'a mut impl AnalyzerBackend, ) -> Result<&'a mut Context, GraphError> { match analyzer.node_mut(*self) { Node::Context(c) => Ok(c), @@ -92,7 +89,7 @@ impl ContextNode { &self, ret_stmt_loc: Loc, ret: ContextVarNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { self.underlying_mut(analyzer)?.ret.push((ret_stmt_loc, ret)); self.propogate_end(analyzer)?; @@ -100,10 +97,7 @@ impl ContextNode { } /// Propogate that this context has ended up the context graph - pub fn propogate_end( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result<(), GraphError> { + pub fn propogate_end(&self, analyzer: &mut impl AnalyzerBackend) -> Result<(), GraphError> { let underlying = &mut self.underlying_mut(analyzer)?; let curr_live = underlying.number_of_live_edges; underlying.number_of_live_edges = 0; diff --git a/crates/graph/src/nodes/context/querying.rs b/crates/graph/src/nodes/context/querying.rs index 8a4ac064..717289eb 100644 --- a/crates/graph/src/nodes/context/querying.rs +++ b/crates/graph/src/nodes/context/querying.rs @@ -12,7 +12,7 @@ impl ContextNode { /// Gets the associated contract for the function for the context pub fn associated_contract( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { Ok(self .associated_fn(analyzer)? @@ -23,7 +23,7 @@ impl ContextNode { /// Tries to get the associated function for the context pub fn maybe_associated_contract( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, GraphError> { Ok(self .associated_fn(analyzer)? @@ -33,7 +33,7 @@ impl ContextNode { /// Tries to get the associated source for the context pub fn maybe_associated_source( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Option { let context = self.underlying(analyzer).unwrap(); if let Some(src) = context.cache.associated_source { @@ -54,7 +54,7 @@ impl ContextNode { /// Tries to get the associated source unit part for the context pub fn associated_source_unit_part( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { if let Some(sup) = self .associated_fn(analyzer)? @@ -71,7 +71,7 @@ impl ContextNode { /// Gets visible functions pub fn visible_modifiers( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, GraphError> { // TODO: filter privates let Some(source) = self.maybe_associated_source(analyzer) else { @@ -142,7 +142,7 @@ impl ContextNode { /// Gets visible functions pub fn visible_funcs( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, GraphError> { // TODO: filter privates if let Some(vis) = &self.underlying(analyzer)?.cache.visible_funcs { @@ -188,7 +188,7 @@ impl ContextNode { /// Gets all visible functions pub fn source_funcs( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Vec { // TODO: filter privates let Some(source) = self.maybe_associated_source(analyzer) else { @@ -211,7 +211,7 @@ impl ContextNode { /// Gets all visible structs pub fn visible_structs( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, GraphError> { // TODO: filter privates if let Some(vis) = &self.underlying(analyzer)?.cache.visible_structs { diff --git a/crates/graph/src/nodes/context/solving.rs b/crates/graph/src/nodes/context/solving.rs index 35f927bf..2c2ff5bc 100644 --- a/crates/graph/src/nodes/context/solving.rs +++ b/crates/graph/src/nodes/context/solving.rs @@ -1,5 +1,5 @@ -use crate::FlattenedRange; use crate::elem::Elem; +use crate::FlattenedRange; use crate::SolcRange; use crate::{ as_dot_str, @@ -30,7 +30,10 @@ impl ContextNode { } /// Get the dependencies as normalized solver atoms - pub fn dep_atoms(&self, analyzer: &mut impl GraphBackend) -> Result, GraphError> { + pub fn dep_atoms( + &self, + analyzer: &mut impl GraphBackend, + ) -> Result, GraphError> { let deps: Vec<_> = self.ctx_deps(analyzer)?; let mut ranges = BTreeMap::default(); deps.iter().try_for_each(|dep| { @@ -78,7 +81,7 @@ impl ContextNode { pub fn add_ctx_dep( &self, dep: ContextVarNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { tracing::trace!( "Adding ctx dependency: {}, is_controllable: {}", @@ -91,7 +94,10 @@ impl ContextNode { // dep.cache_flattened_range(analyzer)?; let mut range = dep.range(analyzer)?.unwrap(); let r = range.flattened_range(analyzer)?.into_owned(); - tracing::trace!("flattened: {}", >::into(r.clone()).as_dot_str(analyzer)); + tracing::trace!( + "flattened: {}", + >::into(r.clone()).as_dot_str(analyzer) + ); // add the atomic constraint if let Some(atom) = Elem::Arena(r.min).atomize(analyzer) { let mut solver = std::mem::take(&mut self.underlying_mut(analyzer)?.dl_solver); diff --git a/crates/graph/src/nodes/context/typing.rs b/crates/graph/src/nodes/context/typing.rs index bd0de0bf..e8a56bda 100644 --- a/crates/graph/src/nodes/context/typing.rs +++ b/crates/graph/src/nodes/context/typing.rs @@ -47,7 +47,7 @@ impl ContextNode { pub fn is_fn_ext( &self, fn_node: FunctionNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { match fn_node.maybe_associated_contract(analyzer) { None => Ok(false), @@ -75,19 +75,13 @@ impl ContextNode { } /// Sets the context to use unchecked math - pub fn set_unchecked( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result<(), GraphError> { + pub fn set_unchecked(&self, analyzer: &mut impl AnalyzerBackend) -> Result<(), GraphError> { self.underlying_mut(analyzer)?.unchecked = true; Ok(()) } /// Sets the context to use checked math - pub fn unset_unchecked( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result<(), GraphError> { + pub fn unset_unchecked(&self, analyzer: &mut impl AnalyzerBackend) -> Result<(), GraphError> { self.underlying_mut(analyzer)?.unchecked = false; Ok(()) } diff --git a/crates/graph/src/nodes/context/var/node.rs b/crates/graph/src/nodes/context/var/node.rs index 5284127e..4fcb102e 100644 --- a/crates/graph/src/nodes/context/var/node.rs +++ b/crates/graph/src/nodes/context/var/node.rs @@ -205,7 +205,10 @@ impl ContextVarNode { Ok(self.underlying(analyzer)?.tmp_of()) } - pub fn struct_to_fields(&self, analyzer: &impl GraphBackend) -> Result, GraphError> { + pub fn struct_to_fields( + &self, + analyzer: &impl GraphBackend, + ) -> Result, GraphError> { if self.ref_range(analyzer)?.is_none() { let fields = analyzer .graph() @@ -309,10 +312,7 @@ impl ContextVarNode { .collect() } - pub fn set_dependent_on( - &self, - analyzer: &mut impl GraphBackend, - ) -> Result<(), GraphError> { + pub fn set_dependent_on(&self, analyzer: &mut impl GraphBackend) -> Result<(), GraphError> { let mut return_self = false; let mut first_iter = true; let mut stack = vec![*self]; @@ -335,7 +335,7 @@ impl ContextVarNode { if first_iter { first_iter = false; - return_self = true; + return_self = true; } } @@ -372,7 +372,7 @@ impl ContextVarNode { if first_iter { first_iter = false; - return_self = true; + return_self = true; } } diff --git a/crates/graph/src/nodes/context/var/ranging.rs b/crates/graph/src/nodes/context/var/ranging.rs index 0cece95e..4a8b20e3 100644 --- a/crates/graph/src/nodes/context/var/ranging.rs +++ b/crates/graph/src/nodes/context/var/ranging.rs @@ -189,7 +189,7 @@ impl ContextVarNode { // #[tracing::instrument(level = "trace", skip_all)] pub fn set_range_min( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, mut new_min: Elem, ) -> Result<(), GraphError> { assert!(self.latest_version(analyzer) == *self); @@ -203,8 +203,6 @@ impl ContextVarNode { new_min.arenaize(analyzer)?; - - // new_min.cache_flatten(analyzer)?; // new_min.cache_minimize(analyzer)?; @@ -238,7 +236,7 @@ impl ContextVarNode { // #[tracing::instrument(level = "trace", skip_all)] pub fn set_range_max( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, mut new_max: Elem, ) -> Result<(), GraphError> { assert!(self.latest_version(analyzer) == *self); @@ -281,7 +279,7 @@ impl ContextVarNode { pub fn set_range_exclusions( &self, analyzer: &mut impl GraphBackend, - mut new_exclusions: Vec, + new_exclusions: Vec, ) -> Result<(), GraphError> { tracing::trace!( "setting range exclusions for {}", @@ -297,7 +295,7 @@ impl ContextVarNode { // let new_exclusions = new_exclusions // .into_iter() // .map(|excl| analyzer.range_arena_idx_or_upsert(excl)) - // .collect(); + // .collect(); self.underlying_mut(analyzer)? .set_range_exclusions(new_exclusions, fallback)?; @@ -306,7 +304,7 @@ impl ContextVarNode { pub fn try_set_range_min( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, mut new_min: Elem, ) -> Result { assert!(self.latest_version(analyzer) == *self); @@ -337,7 +335,7 @@ impl ContextVarNode { pub fn try_set_range_max( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, mut new_max: Elem, ) -> Result { assert!(self.latest_version(analyzer) == *self); @@ -369,7 +367,7 @@ impl ContextVarNode { pub fn try_set_range_exclusions( &self, analyzer: &mut impl GraphBackend, - mut new_exclusions: Vec, + new_exclusions: Vec, ) -> Result { tracing::trace!( "setting range exclusions for: {}", diff --git a/crates/graph/src/nodes/context/var/typing.rs b/crates/graph/src/nodes/context/var/typing.rs index 8b552ba9..5603b8b3 100644 --- a/crates/graph/src/nodes/context/var/typing.rs +++ b/crates/graph/src/nodes/context/var/typing.rs @@ -279,7 +279,7 @@ impl ContextVarNode { loc: Loc, ctx: ContextNode, cast_ty: Builtin, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { let new_underlying = self .underlying(analyzer)? @@ -295,7 +295,7 @@ impl ContextVarNode { &self, loc: Loc, ctx: ContextNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { let new_underlying = self .underlying(analyzer)? @@ -315,7 +315,7 @@ impl ContextVarNode { pub fn cast_from( &self, other: &Self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { let to_ty = other.ty(analyzer)?.clone(); self.cast_from_ty(to_ty, analyzer)?; @@ -325,7 +325,7 @@ impl ContextVarNode { pub fn literal_cast_from( &self, other: &Self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { let to_ty = other.ty(analyzer)?.clone(); self.literal_cast_from_ty(to_ty, analyzer)?; @@ -448,7 +448,7 @@ impl ContextVarNode { pub fn literal_cast_from_ty( &self, to_ty: VarType, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { let from_ty = self.ty(analyzer)?.clone(); if !from_ty.ty_eq(&to_ty, analyzer)? { @@ -466,10 +466,7 @@ impl ContextVarNode { Ok(()) } - pub fn try_increase_size( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result<(), GraphError> { + pub fn try_increase_size(&self, analyzer: &mut impl AnalyzerBackend) -> Result<(), GraphError> { let from_ty = self.ty(analyzer)?.clone(); self.cast_from_ty(from_ty.max_size(analyzer)?, analyzer)?; Ok(()) @@ -482,7 +479,7 @@ impl ContextVarNode { pub fn cast_exprs( &self, to_ty: &VarType, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, Elem)>, GraphError> { if let Some(to_range) = to_ty.range(analyzer)? { let mut min_expr = (*self) diff --git a/crates/graph/src/nodes/context/var/underlying.rs b/crates/graph/src/nodes/context/var/underlying.rs index 500ceda3..5b7f86f3 100644 --- a/crates/graph/src/nodes/context/var/underlying.rs +++ b/crates/graph/src/nodes/context/var/underlying.rs @@ -63,7 +63,7 @@ impl ContextVar { loc: Loc, ctx: ContextNode, concrete_node: ConcreteNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { let name = format!( "tmp_{}({})", @@ -89,7 +89,7 @@ impl ContextVar { loc: Loc, ctx: ContextNode, cast_ty: Builtin, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { let mut new_tmp = self.clone(); new_tmp.loc = Some(loc); @@ -108,7 +108,7 @@ impl ContextVar { &self, loc: Loc, ctx: ContextNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { let mut new_tmp = self.clone(); new_tmp.loc = Some(loc); @@ -144,7 +144,7 @@ impl ContextVar { loc: Loc, struct_node: StructNode, ctx: ContextNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { Ok(ContextVar { loc: Some(loc), @@ -168,7 +168,7 @@ impl ContextVar { loc: Loc, ty_node: TyNode, ctx: ContextNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { Ok(ContextVar { loc: Some(loc), @@ -535,7 +535,7 @@ impl ContextVar { } pub fn new_from_enum_variant( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ctx: ContextNode, loc: Loc, enum_node: EnumNode, @@ -560,7 +560,7 @@ impl ContextVar { } pub fn new_from_index( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, loc: Loc, parent_name: String, parent_display_name: String, @@ -583,7 +583,7 @@ impl ContextVar { } pub fn new_from_func( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, func: FunctionNode, ) -> Result { Ok(ContextVar { @@ -654,7 +654,7 @@ impl ContextVar { pub fn new_from_func_ret( ctx: ContextNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ret: FunctionReturn, ) -> Result, GraphError> { let (is_tmp, name) = if let Some(name) = ret.name { diff --git a/crates/graph/src/nodes/context/variables.rs b/crates/graph/src/nodes/context/variables.rs index ee839759..476ef244 100644 --- a/crates/graph/src/nodes/context/variables.rs +++ b/crates/graph/src/nodes/context/variables.rs @@ -36,7 +36,7 @@ impl ContextNode { pub fn add_var( &self, var: ContextVarNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { // var.cache_range(analyzer)?; let name = var.name(analyzer)?; @@ -108,10 +108,7 @@ impl ContextNode { } /// Reads the current temporary counter and increments the counter - pub fn new_tmp( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result { + pub fn new_tmp(&self, analyzer: &mut impl AnalyzerBackend) -> Result { let context = self.underlying_mut(analyzer)?; let ret = context.tmp_var_ctr; context.tmp_var_ctr += 1; @@ -122,7 +119,7 @@ impl ContextNode { pub fn push_tmp_expr( &self, expr_ret: ExprRet, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { let underlying_mut = self.underlying_mut(analyzer)?; underlying_mut.tmp_expr.push(Some(expr_ret)); @@ -134,7 +131,7 @@ impl ContextNode { pub fn append_tmp_expr( &self, expr_ret: ExprRet, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { let underlying_mut = self.underlying_mut(analyzer)?; match underlying_mut.tmp_expr.pop() { @@ -174,7 +171,7 @@ impl ContextNode { pub fn pop_tmp_expr( &self, loc: Loc, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, GraphError> { let underlying_mut = self.underlying_mut(analyzer)?; if let Some(Some(expr)) = underlying_mut.tmp_expr.pop() { @@ -189,7 +186,7 @@ impl ContextNode { pub fn push_expr( &self, expr_ret: ExprRet, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { tracing::trace!( "pushing: {}, existing: {:?}, path: {}", @@ -211,12 +208,9 @@ impl ContextNode { &self, expr: ExprRet, loc: Loc, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { - tracing::trace!( - "moving expr to {}", - self.path(analyzer) - ); + tracing::trace!("moving expr to {}", self.path(analyzer)); match expr { ExprRet::SingleLiteral(var) => Ok(ExprRet::SingleLiteral( self.maybe_move_var(var.into(), loc, analyzer)?.into(), @@ -239,7 +233,7 @@ impl ContextNode { &self, var: ContextVarNode, loc: Loc, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { let var = var.latest_version(analyzer); if let Some(ctx) = var.maybe_ctx(analyzer) { @@ -273,7 +267,7 @@ impl ContextNode { pub fn pop_expr_latest( &self, loc: Loc, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, GraphError> { let underlying_mut = self.underlying_mut(analyzer)?; if let Some(elem) = underlying_mut.expr_ret_stack.pop() { diff --git a/crates/graph/src/nodes/context/versioning.rs b/crates/graph/src/nodes/context/versioning.rs index 8fda2c5c..714bc308 100644 --- a/crates/graph/src/nodes/context/versioning.rs +++ b/crates/graph/src/nodes/context/versioning.rs @@ -57,7 +57,7 @@ impl ContextNode { /// Gets the first ancestor of this context pub fn first_ancestor( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { if let Some(first_ancestor) = self.underlying(analyzer)?.cache.first_ancestor { Ok(first_ancestor) @@ -285,7 +285,7 @@ impl ContextNode { &self, w1: ContextNode, w2: ContextNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { assert!(matches!(analyzer.node(w1), Node::Context(_))); assert!(matches!(analyzer.node(w2), Node::Context(_))); @@ -315,7 +315,7 @@ impl ContextNode { pub fn set_child_call( &self, call: ContextNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { assert!(matches!(analyzer.node(call), Node::Context(_))); assert!(*self != call, "Tried to set child to self"); @@ -342,10 +342,7 @@ impl ContextNode { } /// Removes the child of this context - pub fn delete_child( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result<(), GraphError> { + pub fn delete_child(&self, analyzer: &mut impl AnalyzerBackend) -> Result<(), GraphError> { if let Some(child) = self.underlying(analyzer)?.child { match child { CallFork::Fork(w1, w2) => { @@ -366,7 +363,7 @@ impl ContextNode { /// parent contexts if all subcontexts of that context are killed pub fn kill( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, kill_loc: Loc, kill_kind: KilledKind, ) -> Result<(), GraphError> { @@ -412,7 +409,7 @@ impl ContextNode { /// Kills if and only if all subcontexts are killed pub fn end_if_all_forks_ended( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, kill_loc: Loc, kill_kind: KilledKind, ) -> Result<(), GraphError> { diff --git a/crates/graph/src/nodes/contract_ty.rs b/crates/graph/src/nodes/contract_ty.rs index 87528211..85cdda7b 100644 --- a/crates/graph/src/nodes/contract_ty.rs +++ b/crates/graph/src/nodes/contract_ty.rs @@ -72,11 +72,7 @@ impl ContractNode { .collect() } - pub fn inherit( - &self, - inherits: Vec, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) { + pub fn inherit(&self, inherits: Vec, analyzer: &mut impl AnalyzerBackend) { let src = self.associated_source(analyzer); let all_contracts = analyzer.search_children_include_via( src.into(), @@ -184,7 +180,7 @@ impl ContractNode { pub fn funcs_mapping( &self, - analyzer: &(impl GraphBackend + Search + AnalyzerBackend), + analyzer: &(impl Search + AnalyzerBackend), ) -> BTreeMap { analyzer .search_children_depth(self.0.into(), &Edge::Func, 1, 0) diff --git a/crates/graph/src/nodes/err_ty.rs b/crates/graph/src/nodes/err_ty.rs index 2630b4f3..30007db0 100644 --- a/crates/graph/src/nodes/err_ty.rs +++ b/crates/graph/src/nodes/err_ty.rs @@ -96,7 +96,7 @@ impl From for Node { impl ErrorParam { pub fn new( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, param: ErrorParameter, ) -> Self { ErrorParam { diff --git a/crates/graph/src/nodes/func_ty.rs b/crates/graph/src/nodes/func_ty.rs index a4db26ef..0fb4f98f 100644 --- a/crates/graph/src/nodes/func_ty.rs +++ b/crates/graph/src/nodes/func_ty.rs @@ -66,10 +66,7 @@ impl FunctionNode { } /// Gets an ordered list of modifiers for a given function - pub fn modifiers( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Vec { + pub fn modifiers(&self, analyzer: &mut impl AnalyzerBackend) -> Vec { if let Some(mods) = &self.underlying(analyzer).unwrap().cache.modifiers { mods.values().copied().collect() } else { @@ -168,7 +165,7 @@ impl FunctionNode { pub fn loc_specified_name( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { if let Some(con) = self.maybe_associated_contract(analyzer) { Ok(format!("{}.{}", con.name(analyzer)?, self.name(analyzer)?)) @@ -177,7 +174,7 @@ impl FunctionNode { } } - pub fn body_ctx(&self, analyzer: &mut (impl GraphBackend + AnalyzerBackend)) -> ContextNode { + pub fn body_ctx(&self, analyzer: &mut impl AnalyzerBackend) -> ContextNode { if let Some(body_ctx) = self.underlying(analyzer).unwrap().cache.body_ctx { body_ctx } else { @@ -197,10 +194,7 @@ impl FunctionNode { } } - pub fn maybe_body_ctx( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Option { + pub fn maybe_body_ctx(&self, analyzer: &mut impl AnalyzerBackend) -> Option { if let Some(body_ctx) = self.underlying(analyzer).unwrap().cache.body_ctx { Some(body_ctx) } else { @@ -221,7 +215,7 @@ impl FunctionNode { pub fn maybe_associated_contract( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Option { if let Some(maybe_contract) = self .underlying(analyzer) @@ -263,7 +257,7 @@ impl FunctionNode { pub fn maybe_associated_source_unit_part( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Option { if let Some(sup) = self .underlying(analyzer) @@ -304,10 +298,7 @@ impl FunctionNode { } } - pub fn associated_source( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> SourceUnitNode { + pub fn associated_source(&self, analyzer: &mut impl AnalyzerBackend) -> SourceUnitNode { if let Some(src) = self.underlying(analyzer).unwrap().cache.associated_source { src.into() } else { @@ -327,7 +318,7 @@ impl FunctionNode { pub fn maybe_associated_source( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Option { if let Some(src) = self.underlying(analyzer).unwrap().cache.associated_source { Some(src.into()) @@ -385,7 +376,7 @@ impl FunctionNode { pub fn set_params_and_ret( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { let underlying = self.underlying(analyzer)?.clone(); let mut params_strs = vec![]; @@ -445,14 +436,16 @@ impl FunctionNode { // // .filter(|edge| Edge::FunctionReturn == *edge.weight()) // // .map(|edge| FunctionReturnNode::from(edge.source())) // // .collect() - // // } + // // } // } - pub fn returns<'a>( - &self, - analyzer: &'a impl GraphBackend, - ) -> &'a [FunctionReturnNode] { - self.underlying(analyzer).unwrap().cache.returns.as_ref().unwrap() + pub fn returns<'a>(&self, analyzer: &'a impl GraphBackend) -> &'a [FunctionReturnNode] { + self.underlying(analyzer) + .unwrap() + .cache + .returns + .as_ref() + .unwrap() } pub fn is_public_or_ext(&self, analyzer: &impl GraphBackend) -> Result { @@ -884,7 +877,7 @@ impl From for Node { impl FunctionParam { pub fn new( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, param: Parameter, order: usize, ) -> Self { @@ -983,10 +976,7 @@ pub struct FunctionReturn { } impl FunctionReturn { - pub fn new( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - param: Parameter, - ) -> Self { + pub fn new(analyzer: &mut impl AnalyzerBackend, param: Parameter) -> Self { FunctionReturn { loc: param.loc, ty: analyzer.parse_expr(¶m.ty, None), diff --git a/crates/graph/src/nodes/msg.rs b/crates/graph/src/nodes/msg.rs index 2b1cb310..e882503c 100644 --- a/crates/graph/src/nodes/msg.rs +++ b/crates/graph/src/nodes/msg.rs @@ -61,7 +61,7 @@ impl Msg { elem: &str, loc: Loc, ctx: ContextNode, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { let (node, name) = match elem { "data" => { @@ -181,7 +181,7 @@ impl Msg { }; let mut var = ContextVar::new_from_concrete(loc, ctx, node.into(), analyzer)?; - var.name = name.clone(); + var.name.clone_from(&name); var.display_name = name; var.is_tmp = false; var.is_symbolic = true; diff --git a/crates/graph/src/nodes/struct_ty.rs b/crates/graph/src/nodes/struct_ty.rs index c10596be..4eef093b 100644 --- a/crates/graph/src/nodes/struct_ty.rs +++ b/crates/graph/src/nodes/struct_ty.rs @@ -197,7 +197,7 @@ impl From for Node { impl Field { pub fn new( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, var_def: VariableDeclaration, ) -> Field { let ty_idx = analyzer.parse_expr(&var_def.ty, None); diff --git a/crates/graph/src/nodes/ty_ty.rs b/crates/graph/src/nodes/ty_ty.rs index 95ff78c4..af658539 100644 --- a/crates/graph/src/nodes/ty_ty.rs +++ b/crates/graph/src/nodes/ty_ty.rs @@ -66,10 +66,7 @@ impl From for Node { } impl Ty { - pub fn new( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ty: TypeDefinition, - ) -> Ty { + pub fn new(analyzer: &mut impl AnalyzerBackend, ty: TypeDefinition) -> Ty { Ty { loc: ty.loc, ty: analyzer.parse_expr(&ty.ty, None), diff --git a/crates/graph/src/nodes/var_ty.rs b/crates/graph/src/nodes/var_ty.rs index 7faeaf02..4391952c 100644 --- a/crates/graph/src/nodes/var_ty.rs +++ b/crates/graph/src/nodes/var_ty.rs @@ -45,7 +45,7 @@ impl VarNode { pub fn parse_initializer( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, parent: NodeIdx, ) -> Result<(), GraphError> { if let Some(expr) = self.underlying(analyzer)?.initializer_expr.clone() { @@ -236,7 +236,7 @@ impl From for Node { impl Var { pub fn new( - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, var: VariableDefinition, in_contract: bool, ) -> Var { diff --git a/crates/graph/src/range/elem/concrete.rs b/crates/graph/src/range/elem/concrete.rs index 97a91ec5..21fa678d 100644 --- a/crates/graph/src/range/elem/concrete.rs +++ b/crates/graph/src/range/elem/concrete.rs @@ -1,4 +1,3 @@ - use crate::{ nodes::{Concrete, ContextVarNode}, range::elem::{Elem, RangeElem}, @@ -7,7 +6,6 @@ use crate::{ use shared::NodeIdx; -use std::collections::BTreeMap; use std::hash::{Hash, Hasher}; use solang_parser::pt::Loc; diff --git a/crates/graph/src/range/elem/elem_enum.rs b/crates/graph/src/range/elem/elem_enum.rs index d35671a4..3252a4c0 100644 --- a/crates/graph/src/range/elem/elem_enum.rs +++ b/crates/graph/src/range/elem/elem_enum.rs @@ -1,6 +1,4 @@ use crate::elem::MinMaxed; -use std::cell::RefCell; -use std::rc::Rc; use crate::{ nodes::{Concrete, ContextVarNode}, range::elem::{ @@ -9,6 +7,8 @@ use crate::{ GraphBackend, GraphError, }; use solang_parser::pt::Loc; +use std::cell::RefCell; +use std::rc::Rc; use shared::{NodeIdx, RangeArenaIdx}; @@ -16,8 +16,8 @@ use ethers_core::types::I256; use tracing::instrument; use std::{ - hash::{Hash,Hasher}, collections::BTreeMap, + hash::{Hash, Hasher}, ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub}, }; @@ -340,12 +340,15 @@ impl Elem { Elem::ConcreteDyn(d) => { d.len.replace_dep(to_replace, replacement.clone(), analyzer); let vals = std::mem::take(&mut d.val); - d.val = vals.into_iter().map(|(mut k, (mut v, op))| { - k.replace_dep(to_replace, replacement.clone(), analyzer); - v.replace_dep(to_replace, replacement.clone(), analyzer); - (k, (v, op)) - }).collect(); - }, + d.val = vals + .into_iter() + .map(|(mut k, (mut v, op))| { + k.replace_dep(to_replace, replacement.clone(), analyzer); + v.replace_dep(to_replace, replacement.clone(), analyzer); + (k, (v, op)) + }) + .collect(); + } Elem::Null => {} Elem::Arena(_) => { let mut s = self.dearenaize(analyzer).borrow().clone(); @@ -368,9 +371,7 @@ impl Elem { pub fn dearenaize(&self, analyzer: &impl GraphBackend) -> Rc> { match self { - Self::Arena(arena_idx) => { - analyzer.range_arena().ranges[*arena_idx].clone() - }, + Self::Arena(arena_idx) => analyzer.range_arena().ranges[*arena_idx].clone(), _ => unreachable!(), } } @@ -563,8 +564,12 @@ impl Elem { } } - pub fn arenaized_flattened(&self, max: bool, analyzer: &impl GraphBackend) -> Option>> { - if let Some(idx) = analyzer.range_arena_idx(self) { + pub fn arenaized_flattened( + &self, + max: bool, + analyzer: &impl GraphBackend, + ) -> Option>> { + if let Some(idx) = analyzer.range_arena_idx(self) { if let Ok(t) = analyzer.range_arena().ranges[idx].try_borrow() { match &*t { Elem::Expr(ref arenaized) => { @@ -588,15 +593,9 @@ impl Elem { arenaized.flattened_min.clone() } } - c @ Elem::Concrete(_) => { - Some(Box::new(c.clone())) - } - c @ Elem::Null => { - Some(Box::new(c.clone())) - } - a @ Elem::Arena(_) => { - a.arenaized_flattened(max, analyzer) - } + c @ Elem::Concrete(_) => Some(Box::new(c.clone())), + c @ Elem::Null => Some(Box::new(c.clone())), + a @ Elem::Arena(_) => a.arenaized_flattened(max, analyzer), } } else { None @@ -606,8 +605,13 @@ impl Elem { } } - pub fn set_arenaized_flattened(&self, max: bool, elem: &Elem, analyzer: &impl GraphBackend) { - if let Some(idx) = analyzer.range_arena_idx(self) { + pub fn set_arenaized_flattened( + &self, + max: bool, + elem: &Elem, + analyzer: &impl GraphBackend, + ) { + if let Some(idx) = analyzer.range_arena_idx(self) { if let Ok(mut t) = analyzer.range_arena().ranges[idx].try_borrow_mut() { match &mut *t { Elem::Expr(ref mut arenaized) => { @@ -633,13 +637,17 @@ impl Elem { } _ => {} } - } } } - pub fn set_arenaized_cache(&self, max: bool, elem: &Elem, analyzer: &impl GraphBackend) { - if let Some(idx) = analyzer.range_arena_idx(self) { + pub fn set_arenaized_cache( + &self, + max: bool, + elem: &Elem, + analyzer: &impl GraphBackend, + ) { + if let Some(idx) = analyzer.range_arena_idx(self) { if let Ok(mut t) = analyzer.range_arena().ranges[idx].try_borrow_mut() { match &mut *t { Elem::Expr(ref mut arenaized) => { @@ -665,7 +673,6 @@ impl Elem { } _ => {} } - } } } @@ -733,15 +740,13 @@ impl RangeElem for Elem { fn arenaize(&mut self, analyzer: &mut impl GraphBackend) -> Result<(), GraphError> { match self { Self::Arena(_) => return Ok(()), - Self::Reference(d) => { - d.arenaize(analyzer)? - }, + Self::Reference(d) => d.arenaize(analyzer)?, Self::ConcreteDyn(d) => d.arenaize(analyzer)?, Self::Expr(expr) => { expr.arenaize(analyzer)?; } Self::Concrete(c) => c.arenaize(analyzer)?, - Self::Null => {}, + Self::Null => {} } let self_take = std::mem::take(self); @@ -819,7 +824,7 @@ impl RangeElem for Elem { // _ => {} // } Ok(res) - }, + } } } @@ -840,7 +845,7 @@ impl RangeElem for Elem { let dearenaized = self.dearenaize(analyzer); let (min, max) = { let Ok(t) = dearenaized.try_borrow() else { - return Ok(()) + return Ok(()); }; let min = t.flatten(false, analyzer)?; @@ -885,7 +890,7 @@ impl RangeElem for Elem { } else { false } - }, + } } } @@ -902,7 +907,7 @@ impl RangeElem for Elem { } else { (false, false) } - }, + } } } @@ -933,7 +938,10 @@ impl RangeElem for Elem { Self::Expr(expr) => expr.recursive_dependent_on(analyzer), Self::ConcreteDyn(d) => d.recursive_dependent_on(analyzer), Self::Null => Ok(vec![]), - Self::Arena(_) => self.dearenaize(analyzer).borrow().recursive_dependent_on(analyzer), + Self::Arena(_) => self + .dearenaize(analyzer) + .borrow() + .recursive_dependent_on(analyzer), } } @@ -964,7 +972,10 @@ impl RangeElem for Elem { Self::Expr(expr) => expr.depends_on(var, seen, analyzer), Self::ConcreteDyn(d) => d.depends_on(var, seen, analyzer), Self::Null => Ok(false), - Self::Arena(_) => self.dearenaize(analyzer).borrow().depends_on(var, seen, analyzer), + Self::Arena(_) => self + .dearenaize(analyzer) + .borrow() + .depends_on(var, seen, analyzer), } } @@ -986,7 +997,9 @@ impl RangeElem for Elem { Self::Null => {} Self::Arena(_idx) => { let dearenaized = self.dearenaize(analyzer); - dearenaized.borrow_mut().filter_recursion(node_idx, new_idx, analyzer); + dearenaized + .borrow_mut() + .filter_recursion(node_idx, new_idx, analyzer); } } } @@ -1018,7 +1031,7 @@ impl RangeElem for Elem { let dearenaized = self.dearenaize(analyzer); let res = { let Ok(t) = dearenaized.try_borrow() else { - return Ok(self.clone()) + return Ok(self.clone()); }; t.maximize(analyzer)? }; @@ -1043,7 +1056,7 @@ impl RangeElem for Elem { assert!(max, "????"); res - }, + } }; Ok(res) } @@ -1076,7 +1089,7 @@ impl RangeElem for Elem { let dearenaized = self.dearenaize(analyzer); let res = { let Ok(t) = dearenaized.try_borrow() else { - return Ok(self.clone()) + return Ok(self.clone()); }; t.minimize(analyzer)? }; @@ -1100,7 +1113,7 @@ impl RangeElem for Elem { let (min, _max) = self.is_min_max_cached(analyzer); assert!(min, "????"); res - }, + } }; Ok(res) } @@ -1115,25 +1128,25 @@ impl RangeElem for Elem { match &*analyzer.range_arena().ranges[idx].borrow() { Reference(dy) => { if let Some(max) = &dy.flattened_max { - return Ok(*max.clone()) + return Ok(*max.clone()); } - }, + } c @ Concrete(_) => return Ok(c.clone()), ConcreteDyn(inner) => { if let Some(max) = &inner.flattened_max { - return Ok(*max.clone()) + return Ok(*max.clone()); } } Expr(expr) => { if let Some(max) = &expr.flattened_max { - return Ok(*max.clone()) + return Ok(*max.clone()); } - }, + } Null => return Ok(Elem::Null), _ => {} } } - + match self { Reference(dy) => dy.simplify_maximize(analyzer), Concrete(inner) => inner.simplify_maximize(analyzer), @@ -1148,7 +1161,7 @@ impl RangeElem for Elem { let res = expr.simplify_maximize(analyzer)?; expr.set_arenaized_flattened(true, res.clone(), analyzer); Ok(res) - }, + } }, Null => Ok(Elem::Null), Arena(_) => { @@ -1191,20 +1204,20 @@ impl RangeElem for Elem { match &*analyzer.range_arena().ranges[idx].borrow() { Reference(dy) => { if let Some(min) = &dy.flattened_min { - return Ok(*min.clone()) + return Ok(*min.clone()); } - }, + } c @ Concrete(_) => return Ok(c.clone()), ConcreteDyn(inner) => { if let Some(min) = &inner.flattened_min { - return Ok(*min.clone()) + return Ok(*min.clone()); } } Expr(expr) => { if let Some(min) = &expr.flattened_min { - return Ok(*min.clone()) + return Ok(*min.clone()); } - }, + } Null => return Ok(Elem::Null), _ => {} } @@ -1224,7 +1237,7 @@ impl RangeElem for Elem { let res = expr.simplify_minimize(analyzer)?; expr.set_arenaized_flattened(false, res.clone(), analyzer); Ok(res) - }, + } }, Null => Ok(Elem::Null), Arena(_) => { @@ -1273,7 +1286,7 @@ impl RangeElem for Elem { let max = expr.maximize(analyzer)?; self.set_arenaized_flattened(true, &max, analyzer); Ok(()) - }, + } }, Null => Ok(()), Arena(_idx) => { @@ -1281,7 +1294,7 @@ impl RangeElem for Elem { if let Ok(mut t) = dearenaized.try_borrow_mut() { t.cache_maximize(analyzer)?; } - + Ok(()) } } @@ -1306,7 +1319,7 @@ impl RangeElem for Elem { let min = expr.minimize(analyzer)?; self.set_arenaized_flattened(false, &min, analyzer); Ok(()) - }, + } }, Null => Ok(()), Arena(_idx) => { diff --git a/crates/graph/src/range/elem/elem_trait.rs b/crates/graph/src/range/elem/elem_trait.rs index 1ee2bd19..7f5c13b3 100644 --- a/crates/graph/src/range/elem/elem_trait.rs +++ b/crates/graph/src/range/elem/elem_trait.rs @@ -6,8 +6,6 @@ use crate::{ use shared::NodeIdx; -use std::collections::BTreeMap; - pub trait RangeElem { type GraphError; /// Flattens an element into an expression or concrete based purely on inputs, calldata, storage, or environment data variables @@ -32,15 +30,9 @@ pub trait RangeElem { /// Uncaches the minimum and maximum fn uncache(&mut self); /// Tries to simplify to maximum(i.e.: leaves symbolic/dynamic values as they are) - fn simplify_maximize( - &self, - analyzer: &impl GraphBackend, - ) -> Result, Self::GraphError>; + fn simplify_maximize(&self, analyzer: &impl GraphBackend) -> Result, Self::GraphError>; /// Tries to simplify to minimum (i.e.: leaves symbolic/dynamic values as they are) - fn simplify_minimize( - &self, - analyzer: &impl GraphBackend, - ) -> Result, Self::GraphError>; + fn simplify_minimize(&self, analyzer: &impl GraphBackend) -> Result, Self::GraphError>; /// Checks if two range elements are equal fn range_eq(&self, other: &Self, analyzer: &impl GraphBackend) -> bool; /// Tries to compare the ordering of two range elements diff --git a/crates/graph/src/range/elem/expr.rs b/crates/graph/src/range/elem/expr.rs index 87c379b6..4ce9abc6 100644 --- a/crates/graph/src/range/elem/expr.rs +++ b/crates/graph/src/range/elem/expr.rs @@ -12,8 +12,6 @@ use std::hash::Hasher; use ethers_core::types::U256; use shared::NodeIdx; -use std::collections::BTreeMap; - pub static SINGLETON_EQ_OPS: &[RangeOp] = &[ RangeOp::Eq, RangeOp::Neq, @@ -48,12 +46,9 @@ pub struct RangeExpr { pub rhs: Box>, } - impl PartialEq for RangeExpr { fn eq(&self, other: &Self) -> bool { - self.lhs == other.lhs - && self.rhs == other.rhs - && self.op == other.op + self.lhs == other.lhs && self.rhs == other.rhs && self.op == other.op } } impl Eq for RangeExpr {} @@ -107,9 +102,13 @@ impl RangeExpr { Elem::Arena(analyzer.range_arena_idx(&self.rhs)?), )); analyzer.range_arena_idx(&expr) - } + } - pub fn arenaized_cache(&self, max: bool, analyzer: &impl GraphBackend) -> Option> { + pub fn arenaized_cache( + &self, + max: bool, + analyzer: &impl GraphBackend, + ) -> Option> { if let Some(idx) = self.arena_idx(analyzer) { let Ok(t) = analyzer.range_arena().ranges[idx].try_borrow() else { return None; @@ -126,7 +125,11 @@ impl RangeExpr { None } - pub fn arenaized_flat_cache(&self, max: bool, analyzer: &impl GraphBackend) -> Option>> { + pub fn arenaized_flat_cache( + &self, + max: bool, + analyzer: &impl GraphBackend, + ) -> Option>> { if let Some(idx) = self.arena_idx(analyzer) { let Ok(t) = analyzer.range_arena().ranges[idx].try_borrow() else { return None; @@ -143,7 +146,12 @@ impl RangeExpr { None } - pub fn set_arenaized_flattened(&self, max: bool, elem: Elem, analyzer: &impl GraphBackend) { + pub fn set_arenaized_flattened( + &self, + max: bool, + elem: Elem, + analyzer: &impl GraphBackend, + ) { if let Some(idx) = self.arena_idx(analyzer) { if let Ok(mut t) = analyzer.range_arena().ranges[idx].try_borrow_mut() { let Elem::Expr(arenaized) = &mut *t else { @@ -158,7 +166,6 @@ impl RangeExpr { } } } - } impl RangeExpr { @@ -215,7 +222,7 @@ impl RangeElem for RangeExpr { } if let Some(arenaized) = self.arenaized_flat_cache(maximize, analyzer) { - return Ok(*arenaized) + return Ok(*arenaized); } Ok(Elem::Expr(RangeExpr::new( @@ -226,8 +233,7 @@ impl RangeElem for RangeExpr { } fn is_flatten_cached(&self, analyzer: &impl GraphBackend) -> bool { - self.flattened_min.is_some() && self.flattened_max.is_some() - || { + self.flattened_min.is_some() && self.flattened_max.is_some() || { if let Some(idx) = self.arena_idx(analyzer) { if let Ok(t) = analyzer.range_arena().ranges[idx].try_borrow() { if let Elem::Expr(ref arenaized) = *t { @@ -260,7 +266,10 @@ impl RangeElem for RangeExpr { (false, false) } }; - (self.minimized.is_some() || arena_cached_min, self.maximized.is_some() || arena_cached_max) + ( + self.minimized.is_some() || arena_cached_min, + self.maximized.is_some() || arena_cached_max, + ) } fn range_ord( @@ -340,7 +349,7 @@ impl RangeElem for RangeExpr { Ok(*cached) } else if let Some(MinMaxed::Minimized(cached)) = self.arenaized_cache(false, analyzer) { Ok(*cached) - } else if self.op == RangeOp::SetIndices { + } else if self.op == RangeOp::SetIndices { self.simplify_exec_op(false, analyzer) } else { self.exec_op(false, analyzer) @@ -357,7 +366,7 @@ impl RangeElem for RangeExpr { } if let Some(arenaized) = self.arenaized_flat_cache(true, analyzer) { - return Ok(*arenaized) + return Ok(*arenaized); } let l = self.lhs.simplify_maximize(analyzer)?; @@ -368,8 +377,7 @@ impl RangeElem for RangeExpr { MaybeCollapsed::Collapsed(collapsed) => Ok(collapsed), MaybeCollapsed::Not(..) => { // Ok(Elem::Expr(RangeExpr::new(l, self.op, r)))//.simplify_exec_op(false, &mut vec![], analyzer) - let res = - RangeExpr::new(l, self.op, r).simplify_exec_op(true, analyzer)?; + let res = RangeExpr::new(l, self.op, r).simplify_exec_op(true, analyzer)?; match res { Elem::Expr(expr) => { match collapse(&expr.lhs, expr.op, &expr.rhs, analyzer) { @@ -397,7 +405,7 @@ impl RangeElem for RangeExpr { } if let Some(arenaized) = self.arenaized_flat_cache(false, analyzer) { - return Ok(*arenaized) + return Ok(*arenaized); } let l = self.lhs.simplify_minimize(analyzer)?; @@ -410,8 +418,7 @@ impl RangeElem for RangeExpr { MaybeCollapsed::Concretes(..) => RangeExpr::new(l, self.op, r).exec_op(false, analyzer), MaybeCollapsed::Collapsed(collapsed) => Ok(collapsed), MaybeCollapsed::Not(..) => { - let res = - RangeExpr::new(l, self.op, r).simplify_exec_op(false, analyzer)?; + let res = RangeExpr::new(l, self.op, r).simplify_exec_op(false, analyzer)?; match res { Elem::Expr(expr) => { match collapse(&expr.lhs, expr.op, &expr.rhs, analyzer) { @@ -441,9 +448,9 @@ impl RangeElem for RangeExpr { let Elem::Expr(this) = this else { this.cache_flatten(analyzer)?; if let Some(t) = this.arenaized_flattened(false, analyzer) { - return Ok(*t) + return Ok(*t); } else { - return Ok(this.clone()) + return Ok(this.clone()); } }; @@ -452,19 +459,19 @@ impl RangeElem for RangeExpr { } if let Some(arenaized) = this.arenaized_flat_cache(false, analyzer) { - return Ok(*arenaized) + return Ok(*arenaized); } let l = this.lhs.simplify_minimize(analyzer)?; let r = this.rhs.simplify_minimize(analyzer)?; let collapsed = collapse(&l, this.op, &r, analyzer); let res = match collapsed { - MaybeCollapsed::Concretes(..) => RangeExpr::new(l, this.op, r).exec_op(false, analyzer), + MaybeCollapsed::Concretes(..) => { + RangeExpr::new(l, this.op, r).exec_op(false, analyzer) + } MaybeCollapsed::Collapsed(collapsed) => Ok(collapsed), MaybeCollapsed::Not(..) => { - - let res = - RangeExpr::new(l, this.op, r).simplify_exec_op(false, analyzer)?; + let res = RangeExpr::new(l, this.op, r).simplify_exec_op(false, analyzer)?; let idx = analyzer.range_arena_idx_or_upsert(res.clone()); match res { @@ -472,13 +479,15 @@ impl RangeElem for RangeExpr { match collapse(&expr.lhs, expr.op, &expr.rhs, analyzer) { MaybeCollapsed::Concretes(..) => { let exec_res = expr.exec_op(false, analyzer)?; - Elem::Arena(idx).set_arenaized_flattened(false, &exec_res, analyzer); - return Ok(exec_res) - }, + Elem::Arena(idx) + .set_arenaized_flattened(false, &exec_res, analyzer); + return Ok(exec_res); + } MaybeCollapsed::Collapsed(collapsed) => { - Elem::Arena(idx).set_arenaized_flattened(false, &collapsed, analyzer); - return Ok(collapsed) - }, + Elem::Arena(idx) + .set_arenaized_flattened(false, &collapsed, analyzer); + return Ok(collapsed); + } _ => {} } Ok(Elem::Expr(expr)) @@ -499,9 +508,9 @@ impl RangeElem for RangeExpr { let Elem::Expr(this) = this else { this.cache_flatten(analyzer)?; if let Some(t) = this.arenaized_flattened(true, analyzer) { - return Ok(*t) + return Ok(*t); } else { - return Ok(this.clone()) + return Ok(this.clone()); } }; @@ -510,19 +519,19 @@ impl RangeElem for RangeExpr { } if let Some(arenaized) = this.arenaized_flat_cache(false, analyzer) { - return Ok(*arenaized) + return Ok(*arenaized); } let l = this.lhs.simplify_maximize(analyzer)?; let r = this.rhs.simplify_maximize(analyzer)?; let collapsed = collapse(&l, this.op, &r, analyzer); let res = match collapsed { - MaybeCollapsed::Concretes(..) => RangeExpr::new(l, this.op, r).exec_op(true, analyzer), + MaybeCollapsed::Concretes(..) => { + RangeExpr::new(l, this.op, r).exec_op(true, analyzer) + } MaybeCollapsed::Collapsed(collapsed) => Ok(collapsed), MaybeCollapsed::Not(..) => { - - let res = - RangeExpr::new(l, this.op, r).simplify_exec_op(true, analyzer)?; + let res = RangeExpr::new(l, this.op, r).simplify_exec_op(true, analyzer)?; let idx = analyzer.range_arena_idx_or_upsert(res.clone()); match res { @@ -530,13 +539,15 @@ impl RangeElem for RangeExpr { match collapse(&expr.lhs, expr.op, &expr.rhs, analyzer) { MaybeCollapsed::Concretes(..) => { let exec_res = expr.exec_op(true, analyzer)?; - Elem::Arena(idx).set_arenaized_flattened(true, &exec_res, analyzer); - return Ok(exec_res) - }, + Elem::Arena(idx) + .set_arenaized_flattened(true, &exec_res, analyzer); + return Ok(exec_res); + } MaybeCollapsed::Collapsed(collapsed) => { - Elem::Arena(idx).set_arenaized_flattened(true, &collapsed, analyzer); - return Ok(collapsed) - }, + Elem::Arena(idx) + .set_arenaized_flattened(true, &collapsed, analyzer); + return Ok(collapsed); + } _ => {} } Ok(Elem::Expr(expr)) @@ -554,7 +565,7 @@ impl RangeElem for RangeExpr { if let Some(idx) = self.arena_idx(g) { if let Elem::Expr(ref arenaized) = *g.range_arena().ranges[idx].borrow() { if arenaized.flattened_max.is_some() { - return Ok(()) + return Ok(()); } }; } else { @@ -574,7 +585,7 @@ impl RangeElem for RangeExpr { if let Some(idx) = self.arena_idx(g) { if let Elem::Expr(ref arenaized) = *g.range_arena().ranges[idx].borrow() { if arenaized.flattened_min.is_some() { - return Ok(()) + return Ok(()); } }; } else { @@ -641,23 +652,23 @@ pub fn collapse<'a, 'b, 'c: 'a + 'b>( match collapse(&t, op, r, analyzer) { MaybeCollapsed::Not(..) => MaybeCollapsed::Not(l, r), MaybeCollapsed::Concretes(..) => MaybeCollapsed::Concretes(l, r), - MaybeCollapsed::Collapsed(e) => MaybeCollapsed::Collapsed(e) + MaybeCollapsed::Collapsed(e) => MaybeCollapsed::Collapsed(e), } } else { MaybeCollapsed::Not(l, r) } - }, + } (l, Elem::Arena(_)) => { if let Ok(t) = r.dearenaize(analyzer).try_borrow() { match collapse(l, op, &t, analyzer) { MaybeCollapsed::Not(..) => MaybeCollapsed::Not(l, r), MaybeCollapsed::Concretes(..) => MaybeCollapsed::Concretes(l, r), - MaybeCollapsed::Collapsed(e) => MaybeCollapsed::Collapsed(e) + MaybeCollapsed::Collapsed(e) => MaybeCollapsed::Collapsed(e), } } else { MaybeCollapsed::Not(l, r) } - }, + } (Elem::Concrete(_), Elem::Concrete(_)) => MaybeCollapsed::Concretes(l, r), (Elem::Expr(expr), d @ Elem::Reference(_)) => { // try to collapse the expression diff --git a/crates/graph/src/range/elem/map_or_array.rs b/crates/graph/src/range/elem/map_or_array.rs index bcd350ea..b0aa3763 100644 --- a/crates/graph/src/range/elem/map_or_array.rs +++ b/crates/graph/src/range/elem/map_or_array.rs @@ -35,9 +35,7 @@ pub struct RangeDyn { impl PartialEq for RangeDyn { fn eq(&self, other: &Self) -> bool { - self.len == other.len - && self.val == other.val - && self.op_num == other.op_num + self.len == other.len && self.val == other.val && self.op_num == other.op_num } } impl Eq for RangeDyn {} @@ -348,8 +346,7 @@ impl RangeElem for RangeDyn { }) .collect(); let flat_max = self.flatten(true, analyzer)?; - let simplified_flat_max = - flat_max.simplify_maximize(analyzer)?; + let simplified_flat_max = flat_max.simplify_maximize(analyzer)?; self.flattened_max = Some(Box::new(simplified_flat_max)); } if self.flattened_min.is_none() { @@ -364,8 +361,7 @@ impl RangeElem for RangeDyn { }) .collect(); let flat_min = self.flatten(false, analyzer)?; - let simplified_flat_min = - flat_min.simplify_minimize(analyzer)?; + let simplified_flat_min = flat_min.simplify_minimize(analyzer)?; self.flattened_min = Some(Box::new(simplified_flat_min)); } Ok(()) @@ -411,10 +407,7 @@ impl RangeElem for RangeDyn { // We dont maximize the key so that any subsequent // `get_index` can find potential values let maximized = val.0.maximize(analyzer)?; - map.insert( - idx.simplify_maximize(analyzer)?, - (maximized, val.1), - ); + map.insert(idx.simplify_maximize(analyzer)?, (maximized, val.1)); } // map.into_iter().filter(|(k, (v, op))| { @@ -439,10 +432,7 @@ impl RangeElem for RangeDyn { // We dont minimize the key so that any subsequent // `get_index` can find potential values let minimized = val.0.minimize(analyzer)?; - map.insert( - idx.simplify_minimize(analyzer)?, - (minimized, val.1), - ); + map.insert(idx.simplify_minimize(analyzer)?, (minimized, val.1)); } // map.into_iter().filter(|(k, (v, op))| { diff --git a/crates/graph/src/range/elem/mod.rs b/crates/graph/src/range/elem/mod.rs index 19ac5c37..cfb54157 100644 --- a/crates/graph/src/range/elem/mod.rs +++ b/crates/graph/src/range/elem/mod.rs @@ -22,14 +22,14 @@ impl MinMaxed { pub fn maxed(self) -> Elem { match self { Self::Maximized(t) => *t, - _ => panic!("MinMaxed was min not max") + _ => panic!("MinMaxed was min not max"), } } pub fn mined(self) -> Elem { match self { Self::Minimized(t) => *t, - _ => panic!("MinMaxed was max not min") + _ => panic!("MinMaxed was max not min"), } } } diff --git a/crates/graph/src/range/elem/reference.rs b/crates/graph/src/range/elem/reference.rs index 2a3940c2..0ac79c12 100644 --- a/crates/graph/src/range/elem/reference.rs +++ b/crates/graph/src/range/elem/reference.rs @@ -13,8 +13,6 @@ use shared::NodeIdx; use solang_parser::pt::Loc; -use std::collections::BTreeMap; - /// A dynamic range element value #[derive(Clone, Debug, Ord, PartialOrd)] pub struct Reference { @@ -43,7 +41,6 @@ impl PartialEq for Reference { } impl Eq for Reference {} - impl Reference { pub fn new(idx: NodeIdx) -> Self { Self { @@ -118,14 +115,13 @@ impl RangeElem for Reference { var: ContextVarNode, seen: &mut Vec, analyzer: &impl GraphBackend, - ) -> Result { + ) -> Result { let cvar = ContextVarNode::from(self.idx); if seen.contains(&cvar) { - return Ok(false) + return Ok(false); } - if cvar == var - || cvar.name(analyzer)? == var.name(analyzer)? && self.idx >= var.0.into() { + if cvar == var || cvar.name(analyzer)? == var.name(analyzer)? && self.idx >= var.0.into() { Ok(true) } else if let Some(range) = cvar.ref_range(analyzer)? { seen.push(cvar); @@ -169,9 +165,9 @@ impl RangeElem for Reference { } fn is_flatten_cached(&self, analyzer: &impl GraphBackend) -> bool { - self.flattened_min.is_some() && self.flattened_max.is_some() - || { - if let Some(idx) = analyzer.range_arena_idx(&Elem::Reference(Reference::new(self.idx))) { + self.flattened_min.is_some() && self.flattened_max.is_some() || { + if let Some(idx) = analyzer.range_arena_idx(&Elem::Reference(Reference::new(self.idx))) + { if let Ok(t) = analyzer.range_arena().ranges[idx].try_borrow() { if let Elem::Reference(ref arenaized) = *t { arenaized.flattened_min.is_some() && arenaized.flattened_max.is_some() @@ -189,7 +185,8 @@ impl RangeElem for Reference { fn is_min_max_cached(&self, analyzer: &impl GraphBackend) -> (bool, bool) { let (arena_cached_min, arena_cached_max) = { - if let Some(idx) = analyzer.range_arena_idx(&Elem::Reference(Reference::new(self.idx))) { + if let Some(idx) = analyzer.range_arena_idx(&Elem::Reference(Reference::new(self.idx))) + { if let Ok(t) = analyzer.range_arena().ranges[idx].try_borrow() { if let Elem::Reference(ref arenaized) = *t { (arenaized.minimized.is_some(), arenaized.maximized.is_some()) @@ -203,7 +200,10 @@ impl RangeElem for Reference { (false, false) } }; - (self.minimized.is_some() || arena_cached_min, self.maximized.is_some() || arena_cached_max) + ( + self.minimized.is_some() || arena_cached_min, + self.maximized.is_some() || arena_cached_max, + ) } fn cache_flatten(&mut self, g: &mut impl GraphBackend) -> Result<(), GraphError> { @@ -215,7 +215,7 @@ impl RangeElem for Reference { if let Elem::Reference(ref arenaized) = *t { if arenaized.flattened_max.is_some() { tracing::trace!("reference cache flatten hit"); - return Ok(()) + return Ok(()); } } } @@ -233,7 +233,7 @@ impl RangeElem for Reference { if let Elem::Reference(ref arenaized) = *t { if arenaized.flattened_min.is_some() { tracing::trace!("reference cache flatten hit"); - return Ok(()) + return Ok(()); } } } @@ -334,7 +334,7 @@ impl RangeElem for Reference { if let Elem::Reference(ref arenaized) = *t { if arenaized.flattened_max.is_some() { tracing::trace!("reference simplify maximize cache hit"); - return Ok(*arenaized.flattened_max.clone().unwrap()) + return Ok(*arenaized.flattened_max.clone().unwrap()); } } } @@ -348,8 +348,7 @@ impl RangeElem for Reference { cvar.global_first_version(analyzer).into(), ))) } else { - self.flatten(true, analyzer)? - .simplify_maximize(analyzer) + self.flatten(true, analyzer)?.simplify_maximize(analyzer) } } @@ -366,7 +365,7 @@ impl RangeElem for Reference { if let Elem::Reference(ref arenaized) = *t { if arenaized.flattened_min.is_some() { tracing::trace!("reference simplify minimize cache hit"); - return Ok(*arenaized.flattened_min.clone().unwrap()) + return Ok(*arenaized.flattened_min.clone().unwrap()); } } } @@ -378,8 +377,7 @@ impl RangeElem for Reference { cvar.global_first_version(analyzer).into(), ))) } else { - self.flatten(false, analyzer)? - .simplify_minimize(analyzer) + self.flatten(false, analyzer)?.simplify_minimize(analyzer) } } diff --git a/crates/graph/src/range/exec/exec_op.rs b/crates/graph/src/range/exec/exec_op.rs index 23911e4c..8de2986d 100644 --- a/crates/graph/src/range/exec/exec_op.rs +++ b/crates/graph/src/range/exec/exec_op.rs @@ -7,7 +7,6 @@ use crate::{ use ethers_core::types::{I256, U256}; use solang_parser::pt::Loc; - impl ExecOp for RangeExpr { type GraphError = GraphError; @@ -23,17 +22,17 @@ impl ExecOp for RangeExpr { if let Elem::Expr(expr) = &*t { if maximize { if let Some(MinMaxed::Maximized(max)) = &expr.maximized { - return Ok(*max.clone()) + return Ok(*max.clone()); } } else if let Some(MinMaxed::Minimized(min)) = &expr.minimized { - return Ok(*min.clone()) + return Ok(*min.clone()); } } } } let res = self.exec(self.spread(analyzer)?, maximize, analyzer)?; - + if let Some(idx) = idx { if let Ok(mut t) = analyzer.range_arena().ranges[idx].try_borrow_mut() { if let Elem::Expr(expr) = &mut *t { @@ -70,9 +69,9 @@ impl ExecOp for RangeExpr { if let Ok(mut t) = analyzer.range_arena().ranges[idx].try_borrow_mut() { if let Elem::Expr(expr) = &mut *t { if maximize { - expr.maximized = self.maximized.clone(); + expr.maximized.clone_from(&self.maximized); } else { - expr.minimized = self.minimized.clone(); + expr.minimized.clone_from(&self.minimized); } } } @@ -101,7 +100,7 @@ impl ExecOp for RangeExpr { } if let Some(v) = self.arenaized_flat_cache(maximize, analyzer) { - return Ok(*v) + return Ok(*v); } let (lhs_min, lhs_max, rhs_min, rhs_max) = self.simplify_spread(analyzer)?; @@ -157,7 +156,7 @@ impl ExecOp for RangeExpr { }; finished = true; } - RangeOp::SetLength => { + RangeOp::SetLength => { ret = if maximize { Ok(lhs_max .range_set_length(&rhs_max) @@ -256,10 +255,10 @@ impl ExecOp for RangeExpr { match (lhs_is_conc, rhs_is_conc, finished) { (true, true, false) => { ret = self.exec(parts, maximize, analyzer); - }, + } (_, _, false) => { ret = Ok(Elem::Expr(self.clone())); - }, + } _ => {} } @@ -283,10 +282,10 @@ impl ExecOp for RangeExpr { > { let lhs_min = self.lhs.minimize(analyzer)?; self.lhs.set_arenaized_cache(false, &lhs_min, analyzer); - + let lhs_max = self.lhs.maximize(analyzer)?; self.lhs.set_arenaized_cache(true, &lhs_max, analyzer); - + let rhs_min = self.rhs.minimize(analyzer)?; self.rhs.set_arenaized_cache(false, &rhs_min, analyzer); @@ -338,17 +337,17 @@ impl ExecOp for RangeExpr { if maximize { if let Some(MinMaxed::Maximized(v)) = self.arenaized_cache(maximize, analyzer) { tracing::trace!("avoided execing via cache"); - return Ok(*v) + return Ok(*v); } } if !maximize { if let Some(MinMaxed::Minimized(v)) = self.arenaized_cache(maximize, analyzer) { tracing::trace!("avoided execing via cache"); - return Ok(*v) + return Ok(*v); } } - + tracing::trace!( "executing {}: {} {} {}, lhs_min: {}, lhs_max: {}, rhs_min: {}, rhs_max: {}", if maximize { "maximum" } else { "minimum" }, @@ -451,8 +450,7 @@ impl ExecOp for RangeExpr { )? .unwrap_or_else(|| Elem::Null)), Elem::Reference(_) => { - let new_max = - lhs_max.simplify_maximize(analyzer)?; + let new_max = lhs_max.simplify_maximize(analyzer)?; if new_max == lhs_max { Ok(Elem::Null) } else { @@ -499,8 +497,7 @@ impl ExecOp for RangeExpr { )? .unwrap_or_else(|| Elem::Null)), Elem::Reference(ref _r) => { - let new_min = - lhs_min.simplify_minimize(analyzer)?; + let new_min = lhs_min.simplify_minimize(analyzer)?; if new_min == lhs_min { Ok(Elem::Null) } else { @@ -516,9 +513,7 @@ impl ExecOp for RangeExpr { } RangeOp::SetIndices => { if maximize { - let max = self - .rhs - .simplify_maximize(analyzer)?; + let max = self.rhs.simplify_maximize(analyzer)?; lhs_max.range_set_indices(&rhs_max).unwrap_or_else(|| { lhs_max @@ -526,9 +521,7 @@ impl ExecOp for RangeExpr { .unwrap_or_else(|| fallback(self, lhs_min, rhs_min, consts)) }) } else { - let min = self - .rhs - .simplify_minimize(analyzer)?; + let min = self.rhs.simplify_minimize(analyzer)?; lhs_min.range_set_indices(&rhs_min).unwrap_or_else(|| { lhs_min .range_set_indices(&min) diff --git a/crates/graph/src/range/exec/mem_ops/mem_set.rs b/crates/graph/src/range/exec/mem_ops/mem_set.rs index 74f3b9d1..6fb7028f 100644 --- a/crates/graph/src/range/exec/mem_ops/mem_set.rs +++ b/crates/graph/src/range/exec/mem_ops/mem_set.rs @@ -182,7 +182,7 @@ impl RangeMemSet for Elem { match (self, other) { (Elem::ConcreteDyn(a), Elem::ConcreteDyn(b)) => { let mut a = a.clone(); - a.len = b.len.clone(); + a.len.clone_from(&b.len); Some(Elem::ConcreteDyn(a.clone())) } (a @ Elem::Concrete(_), _b @ Elem::Concrete(_)) => Some(a.clone()), diff --git a/crates/graph/src/range/exec_traits.rs b/crates/graph/src/range/exec_traits.rs index d32125ed..6fb33895 100644 --- a/crates/graph/src/range/exec_traits.rs +++ b/crates/graph/src/range/exec_traits.rs @@ -1,5 +1,4 @@ use crate::{range::elem::Elem, GraphBackend}; -use std::collections::BTreeMap; /// For execution of operations to be performed on range expressions pub trait ExecOp { diff --git a/crates/graph/src/range/solc_range.rs b/crates/graph/src/range/solc_range.rs index 53c3b5a6..cb6bd8a8 100644 --- a/crates/graph/src/range/solc_range.rs +++ b/crates/graph/src/range/solc_range.rs @@ -8,7 +8,6 @@ use shared::NodeIdx; use ethers_core::types::{Address, H256, I256, U256}; use solang_parser::pt::Loc; -use tracing::instrument; use std::{borrow::Cow, collections::BTreeMap}; @@ -21,11 +20,14 @@ pub struct FlattenedRange { impl From for SolcRange { fn from(range: FlattenedRange) -> Self { - SolcRange::new(Elem::Arena(range.min), Elem::Arena(range.max), range.exclusions) + SolcRange::new( + Elem::Arena(range.min), + Elem::Arena(range.max), + range.exclusions, + ) } } - #[derive(Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash)] pub struct SolcRange { pub min: Elem, @@ -112,10 +114,8 @@ impl SolcRange { analyzer: &mut impl GraphBackend, ) { if let Some(ref mut flattened) = &mut self.flattened { - Elem::Arena(flattened.min) - .replace_dep(to_replace, replacement.clone(), analyzer); - Elem::Arena(flattened.max) - .replace_dep(to_replace, replacement.clone(), analyzer); + Elem::Arena(flattened.min).replace_dep(to_replace, replacement.clone(), analyzer); + Elem::Arena(flattened.max).replace_dep(to_replace, replacement.clone(), analyzer); } self.min .replace_dep(to_replace, replacement.clone(), analyzer); @@ -553,7 +553,10 @@ impl SolcRange { Self::new(min.clone().max(max.clone()), min.max(max), self.exclusions) } - pub fn into_flattened_range(&mut self, analyzer: &mut impl GraphBackend) -> Result { + pub fn into_flattened_range( + &mut self, + analyzer: &mut impl GraphBackend, + ) -> Result { if let Some(cached) = &self.flattened { return Ok(cached.clone()); } @@ -571,7 +574,11 @@ impl SolcRange { let min = analyzer.range_arena_idx_or_upsert(simp_min); let max = analyzer.range_arena_idx_or_upsert(simp_max); - let flat_range = FlattenedRange { min, max, exclusions: self.exclusions.clone() }; + let flat_range = FlattenedRange { + min, + max, + exclusions: self.exclusions.clone(), + }; self.flattened = Some(flat_range.clone()); Ok(flat_range) @@ -602,12 +609,14 @@ impl Range for SolcRange { if self.max_cached.is_none() { let max = self.range_max_mut(); max.cache_maximize(analyzer)?; - self.max_cached = Some(analyzer.range_arena_idx_or_upsert(self.range_max().maximize(analyzer)?)); + self.max_cached = + Some(analyzer.range_arena_idx_or_upsert(self.range_max().maximize(analyzer)?)); } if self.min_cached.is_none() { let min = self.range_min_mut(); min.cache_minimize(analyzer)?; - self.min_cached = Some(analyzer.range_arena_idx_or_upsert(self.range_min().minimize(analyzer)?)); + self.min_cached = + Some(analyzer.range_arena_idx_or_upsert(self.range_min().minimize(analyzer)?)); } Ok(()) } @@ -646,7 +655,11 @@ impl Range for SolcRange { } fn range_exclusions(&self) -> Vec { - self.exclusions.clone().into_iter().map(Elem::Arena).collect() + self.exclusions + .clone() + .into_iter() + .map(Elem::Arena) + .collect() } fn set_range_min(&mut self, new: Self::ElemTy) { self.min_cached = None; @@ -703,9 +716,9 @@ impl Range for SolcRange { let Some(flat) = &self.flattened else { unreachable!(); }; - return Ok(Cow::Borrowed(flat)) + return Ok(Cow::Borrowed(flat)); } else if let Some(flat) = &self.flattened { - return Ok(Cow::Borrowed(flat)) + return Ok(Cow::Borrowed(flat)); } else { unreachable!() } diff --git a/crates/graph/src/solvers/atoms.rs b/crates/graph/src/solvers/atoms.rs index 8a47b1c1..8a46d9de 100644 --- a/crates/graph/src/solvers/atoms.rs +++ b/crates/graph/src/solvers/atoms.rs @@ -9,7 +9,7 @@ use crate::{ }; use ethers_core::types::U256; -use std::{collections::BTreeMap, cell::RefCell, rc::Rc}; +use std::{collections::BTreeMap, rc::Rc}; #[derive(Debug, Clone, Eq, PartialEq, Hash, Ord, PartialOrd)] pub enum AtomOrPart { @@ -306,15 +306,13 @@ impl Atomize for Elem { } (Elem::Concrete(_), Elem::Concrete(_)) => { expr.clone().arenaize(analyzer); - let res = expr - .exec_op(true, analyzer) - .unwrap(); + let res = expr.exec_op(true, analyzer).unwrap(); if res == Elem::Expr(expr.clone()) { AtomOrPart::Part(res) } else { res.atoms_or_part(analyzer) } - }, + } (Elem::ConcreteDyn(_), _) => AtomOrPart::Part(Elem::Null), (_, Elem::ConcreteDyn(_)) => AtomOrPart::Part(Elem::Null), (Elem::Null, _) => AtomOrPart::Part(Elem::Null), @@ -353,18 +351,16 @@ impl Atomize for Elem { a.update_max_ty(); Some(a) } - Arena(_) => { - match &*self.dearenaize(analyzer).borrow() { - e @ Expr(_) => { - let AtomOrPart::Atom(mut a) = e.atoms_or_part(analyzer) else { - return None; - }; - a.update_max_ty(); - Some(a) - } - _ => None + Arena(_) => match &*self.dearenaize(analyzer).borrow() { + e @ Expr(_) => { + let AtomOrPart::Atom(mut a) = e.atoms_or_part(analyzer) else { + return None; + }; + a.update_max_ty(); + Some(a) } - } + _ => None, + }, } } } diff --git a/crates/graph/src/solvers/brute.rs b/crates/graph/src/solvers/brute.rs index fa6ed146..55c00381 100644 --- a/crates/graph/src/solvers/brute.rs +++ b/crates/graph/src/solvers/brute.rs @@ -12,23 +12,23 @@ use ethers_core::types::U256; use std::collections::BTreeMap; pub trait SolcSolver { - fn simplify(&mut self, analyzer: &(impl GraphBackend + AnalyzerBackend)); + fn simplify(&mut self, analyzer: &impl AnalyzerBackend); fn solve( &mut self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result; fn recurse_check( &mut self, idx: usize, solved_atomics: &mut Vec, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result; fn check( &mut self, solved_for: usize, lmr: (Elem, Elem, Elem), solved_atomics: &mut Vec, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(bool, Option), GraphError>; } @@ -270,11 +270,11 @@ impl BruteBinSearchSolver { } impl SolcSolver for BruteBinSearchSolver { - fn simplify(&mut self, _analyzer: &(impl GraphBackend + AnalyzerBackend)) {} + fn simplify(&mut self, _analyzer: &impl AnalyzerBackend) {} fn solve( &mut self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { // pick a value for a variable. check if it satisfies all dependendies // if is sat, try to reduce using bin search? Not sure how that will @@ -430,7 +430,7 @@ impl SolcSolver for BruteBinSearchSolver { &mut self, i: usize, solved_atomics: &mut Vec, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { // println!("recurse check for: {}", self.atomics[i].idxs[0].display_name(analyzer).unwrap()); if i >= self.lmrs.len() { @@ -514,7 +514,7 @@ impl SolcSolver for BruteBinSearchSolver { solved_for_idx: usize, (low, mid, high): (Elem, Elem, Elem), solved_atomics: &mut Vec, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(bool, Option), GraphError> { let solved_dep = &self.atomics[solved_for_idx].clone(); diff --git a/crates/graph/src/solvers/dl.rs b/crates/graph/src/solvers/dl.rs index 34bda3e2..fdbe646b 100644 --- a/crates/graph/src/solvers/dl.rs +++ b/crates/graph/src/solvers/dl.rs @@ -14,7 +14,7 @@ use petgraph::{ Directed, }; -use std::{rc::Rc, collections::BTreeMap}; +use std::{collections::BTreeMap, rc::Rc}; pub type DLGraph = StableGraph; @@ -197,7 +197,8 @@ impl DLSolver { constraint.clone(), Self::dl_atom_normalize(constraint.clone(), analyzer), ) - }).collect::>>>() + }) + .collect::>>>() } pub fn dl_solvable_constraints(&self) -> Vec>> { @@ -594,9 +595,9 @@ impl DLSolver { ty: OpType::DL, lhs: constraint.rhs.clone(), op: RangeOp::Sub(true), - rhs: Rc::new(AtomOrPart::Part(Elem::from(Concrete::from( - U256::from(1), - )))), + rhs: Rc::new(AtomOrPart::Part(Elem::from(Concrete::from(U256::from( + 1, + ))))), })), }, analyzer, diff --git a/crates/graph/src/var_type.rs b/crates/graph/src/var_type.rs index 9bd42d87..b56d1df0 100644 --- a/crates/graph/src/var_type.rs +++ b/crates/graph/src/var_type.rs @@ -135,7 +135,7 @@ impl VarType { pub fn concrete_to_builtin( &mut self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result<(), GraphError> { if let VarType::Concrete(cnode) = self { let c = cnode.underlying(analyzer)?.clone(); @@ -257,7 +257,7 @@ impl VarType { pub fn try_cast( self, other: &Self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, GraphError> { match (self, other) { (l, Self::User(TypeNode::Ty(ty), o_r)) => { @@ -314,7 +314,7 @@ impl VarType { pub fn try_literal_cast( self, other: &Self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result, GraphError> { match (self, other) { (Self::BuiltIn(from_bn, sr), Self::User(TypeNode::Ty(ty), _)) => { @@ -387,10 +387,7 @@ impl VarType { } } - pub fn max_size( - &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), - ) -> Result { + pub fn max_size(&self, analyzer: &mut impl AnalyzerBackend) -> Result { match self { Self::BuiltIn(from_bn, _r) => { let bn = from_bn.max_size(analyzer)?; @@ -645,7 +642,7 @@ impl VarType { pub fn dynamic_underlying_ty( &self, - analyzer: &mut (impl GraphBackend + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ) -> Result { match self { Self::BuiltIn(node, _) => node.dynamic_underlying_ty(analyzer), diff --git a/crates/pyrometer/src/analyzer.rs b/crates/pyrometer/src/analyzer.rs index 627f3f83..0bae6119 100644 --- a/crates/pyrometer/src/analyzer.rs +++ b/crates/pyrometer/src/analyzer.rs @@ -4,9 +4,10 @@ use shared::RangeArena; use analyzers::LocStrSpan; use graph::{nodes::*, ContextEdge, Edge, Node, VarType}; -use shared::{AnalyzerLike, GraphLike, NodeIdx, Search, JoinStats}; +use shared::{AnalyzerLike, GraphLike, JoinStats, NodeIdx, Search}; use solc_expressions::{ExprErr, FnCallBuilder, IntoExprErr, StatementParser}; +use ahash::AHashMap; use ariadne::{Cache, Color, Config, Fmt, Label, Report, ReportKind, Source, Span}; use petgraph::{graph::*, stable_graph::StableGraph, Directed}; use serde_json::Value; @@ -19,13 +20,12 @@ use solang_parser::{ StructDefinition, TypeDefinition, Using, UsingList, VariableDefinition, }, }; -use ahash::AHashMap; use std::{ - collections::{BTreeMap, HashMap}, + cell::RefCell, + collections::BTreeMap, fs, path::{Path, PathBuf}, - cell::RefCell, rc::Rc, }; diff --git a/crates/pyrometer/src/analyzer_backend.rs b/crates/pyrometer/src/analyzer_backend.rs index c0ea6324..97de48d9 100644 --- a/crates/pyrometer/src/analyzer_backend.rs +++ b/crates/pyrometer/src/analyzer_backend.rs @@ -7,14 +7,14 @@ use graph::{ }, AnalyzerBackend, Edge, Node, VarType, }; -use shared::{AnalyzerLike, GraphLike, NodeIdx, JoinStats}; +use shared::{AnalyzerLike, GraphLike, JoinStats, NodeIdx}; use solc_expressions::{ExprErr, IntoExprErr}; +use ahash::AHashMap; use ethers_core::types::U256; use solang_parser::{helpers::CodeLocation, pt::Expression}; -use ahash::AHashMap; -use std::collections::{BTreeMap, HashMap}; +use std::collections::BTreeMap; impl AnalyzerBackend for Analyzer {} diff --git a/crates/pyrometer/src/builtin_fns.rs b/crates/pyrometer/src/builtin_fns.rs index 9fbc0fcb..1c3caeaa 100644 --- a/crates/pyrometer/src/builtin_fns.rs +++ b/crates/pyrometer/src/builtin_fns.rs @@ -1,5 +1,5 @@ use graph::nodes::{Builtin, Function, FunctionParam, FunctionReturn}; -use shared::{AnalyzerLike, GraphLike, StorageLocation}; +use shared::{AnalyzerLike, StorageLocation}; use solang_parser::pt::{FunctionAttribute, Identifier, Loc, Visibility}; @@ -325,7 +325,7 @@ pub fn builtin_fns() -> AHashMap { } pub fn builtin_fns_inputs( - analyzer: &mut (impl GraphLike + AnalyzerLike), + analyzer: &mut impl AnalyzerLike, ) -> AHashMap, Vec)> { let funcs = [ ("wrap", vec![], vec![]), diff --git a/crates/pyrometer/src/graph_backend.rs b/crates/pyrometer/src/graph_backend.rs index 158380cd..bb859a23 100644 --- a/crates/pyrometer/src/graph_backend.rs +++ b/crates/pyrometer/src/graph_backend.rs @@ -1,13 +1,13 @@ -use std::hash::Hasher; -use std::collections::hash_map::DefaultHasher; -use std::hash::Hash; -use std::cell::RefCell; -use std::rc::Rc; use crate::Analyzer; use graph::elem::Elem; use graph::elem::RangeElem; use graph::nodes::Concrete; use shared::RangeArena; +use std::cell::RefCell; +use std::collections::hash_map::DefaultHasher; +use std::hash::Hash; +use std::hash::Hasher; +use std::rc::Rc; use graph::{ as_dot_str, nodes::ContextNode, AnalyzerBackend, AsDotStr, ContextEdge, Edge, GraphBackend, @@ -46,7 +46,7 @@ impl GraphLike for Analyzer { if let Elem::Arena(idx) = elem { Some(*idx) } else { - self.range_arena().map.get(elem).copied() + self.range_arena().map.get(elem).copied() } } @@ -94,15 +94,15 @@ impl GraphLike for Analyzer { idx } else { let idx = self.range_arena().ranges.len(); - self.range_arena_mut().ranges.push(Rc::new(RefCell::new(elem.clone()))); + self.range_arena_mut() + .ranges + .push(Rc::new(RefCell::new(elem.clone()))); self.range_arena_mut().map.insert(elem, idx); idx } } } - - fn calculate_hash(t: &T) -> u64 { let mut s = DefaultHasher::new(); t.hash(&mut s); diff --git a/crates/pyrometer/tests/helpers.rs b/crates/pyrometer/tests/helpers.rs index 687dbd24..3a14b641 100644 --- a/crates/pyrometer/tests/helpers.rs +++ b/crates/pyrometer/tests/helpers.rs @@ -10,7 +10,6 @@ use std::collections::BTreeMap; use std::collections::HashMap; use std::path::PathBuf; - pub fn assert_no_parse_errors(path_str: String) { let sol = std::fs::read_to_string(path_str.clone()).unwrap(); let mut analyzer = Analyzer::default(); @@ -18,11 +17,11 @@ pub fn assert_no_parse_errors(path_str: String) { let _ = analyzer.parse(&sol, ¤t_path, true); assert!( analyzer.expr_errs.is_empty(), - "Analyzer encountered parse errors in {}", path_str + "Analyzer encountered parse errors in {}", + path_str ); } - pub fn assert_no_ctx_killed(path_str: String, sol: &str) { let mut analyzer = Analyzer::default(); let current_path = SourcePath::SolidityFile(PathBuf::from(path_str.clone())); diff --git a/crates/queries/src/lib.rs b/crates/queries/src/lib.rs index 3ac5e78c..325bbed8 100644 --- a/crates/queries/src/lib.rs +++ b/crates/queries/src/lib.rs @@ -1 +1 @@ -//! Currently Empty \ No newline at end of file +//! Currently Empty diff --git a/crates/shared/src/analyzer_like.rs b/crates/shared/src/analyzer_like.rs index 7046d4f4..7c901612 100644 --- a/crates/shared/src/analyzer_like.rs +++ b/crates/shared/src/analyzer_like.rs @@ -2,7 +2,7 @@ use crate::{GraphLike, NodeIdx}; use ahash::AHashMap; -use std::collections::{BTreeMap, HashMap}; +use std::collections::BTreeMap; #[derive(Debug, Clone, Copy, Default)] pub struct JoinStats { @@ -21,75 +21,69 @@ pub struct JoinStats { impl JoinStats { pub fn total_joins(&self) -> usize { - self.total_pure_joins() - + self.total_view_joins() - + self.total_mut_joins() + self.total_pure_joins() + self.total_view_joins() + self.total_mut_joins() } pub fn completed_joins(&self) -> usize { - self.completed_pure_joins() - + self.completed_view_joins() - + self.completed_mut_joins() + self.completed_pure_joins() + self.completed_view_joins() + self.completed_mut_joins() } pub fn reduced_vars(&self) -> usize { - self.pure_reduced_vars() - + self.view_reduced_vars() - + self.mut_reduced_vars() + self.pure_reduced_vars() + self.view_reduced_vars() + self.mut_reduced_vars() } pub fn total_pure_joins(&self) -> usize { self.pure_no_children_joins.num_joins - + self.pure_children_no_forks_joins.num_joins - + self.pure_children_forks_joins.num_joins + + self.pure_children_no_forks_joins.num_joins + + self.pure_children_forks_joins.num_joins } pub fn completed_pure_joins(&self) -> usize { self.pure_no_children_joins.completed_joins - + self.pure_children_no_forks_joins.completed_joins - + self.pure_children_forks_joins.completed_joins + + self.pure_children_no_forks_joins.completed_joins + + self.pure_children_forks_joins.completed_joins } pub fn pure_reduced_vars(&self) -> usize { self.pure_no_children_joins.vars_reduced - + self.pure_children_no_forks_joins.vars_reduced - + self.pure_children_forks_joins.vars_reduced + + self.pure_children_no_forks_joins.vars_reduced + + self.pure_children_forks_joins.vars_reduced } pub fn total_view_joins(&self) -> usize { self.view_no_children_joins.num_joins - + self.view_children_no_forks_joins.num_joins - + self.view_children_forks_joins.num_joins + + self.view_children_no_forks_joins.num_joins + + self.view_children_forks_joins.num_joins } pub fn completed_view_joins(&self) -> usize { self.view_no_children_joins.completed_joins - + self.view_children_no_forks_joins.completed_joins - + self.view_children_forks_joins.completed_joins + + self.view_children_no_forks_joins.completed_joins + + self.view_children_forks_joins.completed_joins } pub fn view_reduced_vars(&self) -> usize { self.view_no_children_joins.vars_reduced - + self.view_children_no_forks_joins.vars_reduced - + self.view_children_forks_joins.vars_reduced + + self.view_children_no_forks_joins.vars_reduced + + self.view_children_forks_joins.vars_reduced } pub fn total_mut_joins(&self) -> usize { self.mut_no_children_joins.num_joins - + self.mut_children_no_forks_joins.num_joins - + self.mut_children_forks_joins.num_joins + + self.mut_children_no_forks_joins.num_joins + + self.mut_children_forks_joins.num_joins } pub fn completed_mut_joins(&self) -> usize { self.mut_no_children_joins.completed_joins - + self.mut_children_no_forks_joins.completed_joins - + self.mut_children_forks_joins.completed_joins + + self.mut_children_no_forks_joins.completed_joins + + self.mut_children_forks_joins.completed_joins } pub fn mut_reduced_vars(&self) -> usize { self.mut_no_children_joins.vars_reduced - + self.mut_children_no_forks_joins.vars_reduced - + self.mut_children_forks_joins.vars_reduced + + self.mut_children_no_forks_joins.vars_reduced + + self.mut_children_forks_joins.vars_reduced } } @@ -97,12 +91,9 @@ impl JoinStats { pub struct JoinStat { pub num_joins: usize, pub completed_joins: usize, - pub vars_reduced: usize + pub vars_reduced: usize, } - - - pub trait AnalyzerLike: GraphLike { /// The expression type type Expr; diff --git a/crates/shared/src/graph_like.rs b/crates/shared/src/graph_like.rs index 69853082..e1c7ba6c 100644 --- a/crates/shared/src/graph_like.rs +++ b/crates/shared/src/graph_like.rs @@ -1,16 +1,17 @@ -use crate::{Heirarchical, AnalyzerLike}; - +use crate::{AnalyzerLike, Heirarchical}; +use ahash::AHashMap; use petgraph::{ graph::{EdgeIndex, Graph, NodeIndex}, Directed, }; -use ahash::AHashMap; use std::{ + cell::RefCell, collections::BTreeSet, + hash::Hash, + rc::Rc, sync::{Arc, Mutex}, - cell::RefCell, rc::Rc, hash::Hash, }; pub type NodeIdx = NodeIndex; diff --git a/crates/solc-expressions/src/assign.rs b/crates/solc-expressions/src/assign.rs index 567fec7c..c3759746 100644 --- a/crates/solc-expressions/src/assign.rs +++ b/crates/solc-expressions/src/assign.rs @@ -4,7 +4,7 @@ use crate::{ }; use graph::{ - elem::{RangeElem, Elem}, + elem::{Elem, RangeElem}, nodes::{ContextNode, ContextVarNode, ExprRet}, AnalyzerBackend, ContextEdge, Edge, GraphError, Node, }; @@ -131,21 +131,23 @@ pub trait Assign: AnalyzerBackend + Sized Elem::from(rhs_cvar.latest_version(self)), ); - - - let needs_forcible = new_lower_bound.depends_on(lhs_cvar, &mut vec![], self).into_expr_err(loc)? - || new_upper_bound.depends_on(lhs_cvar, &mut vec![], self).into_expr_err(loc)?; + let needs_forcible = new_lower_bound + .depends_on(lhs_cvar, &mut vec![], self) + .into_expr_err(loc)? + || new_upper_bound + .depends_on(lhs_cvar, &mut vec![], self) + .into_expr_err(loc)?; let new_lhs = if needs_forcible { self.advance_var_in_ctx_forcible(lhs_cvar.latest_version(self), loc, ctx, true)? } else { - self.advance_var_in_ctx(lhs_cvar.latest_version(self), loc, ctx)? + self.advance_var_in_ctx(lhs_cvar.latest_version(self), loc, ctx)? }; - + new_lhs.underlying_mut(self).into_expr_err(loc)?.tmp_of = rhs_cvar.tmp_of(self).into_expr_err(loc)?; - - if let Some(ref mut dep_on) = new_lhs.underlying_mut(self).into_expr_err(loc)?.dep_on { + + if let Some(ref mut dep_on) = new_lhs.underlying_mut(self).into_expr_err(loc)?.dep_on { dep_on.push(rhs_cvar) } else { new_lhs.set_dependent_on(self).into_expr_err(loc)?; @@ -240,11 +242,14 @@ pub trait Assign: AnalyzerBackend + Sized let field_name = field.name(self).unwrap(); let field_name = field_name.split('.').collect::>()[1]; let new_name = format!("{}.{field_name}", lhs_cvar.name(self).unwrap()); - new_var.name = new_name.clone(); + new_var.name.clone_from(&new_name); new_var.display_name = new_name; - let new_field = - ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); - self.add_edge(new_field, lhs_cvar.first_version(self), Edge::Context(ContextEdge::AttrAccess("field"))); + let new_field = ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); + self.add_edge( + new_field, + lhs_cvar.first_version(self), + Edge::Context(ContextEdge::AttrAccess("field")), + ); }) } } diff --git a/crates/solc-expressions/src/bin_op.rs b/crates/solc-expressions/src/bin_op.rs index 27d0924c..a0f6c475 100644 --- a/crates/solc-expressions/src/bin_op.rs +++ b/crates/solc-expressions/src/bin_op.rs @@ -164,9 +164,8 @@ pub trait BinOp: AnalyzerBackend + Sized { let new_lhs = if assign { let new = self.advance_var_in_ctx_forcible(lhs_cvar, loc, ctx, true)?; let underlying = new.underlying_mut(self).into_expr_err(loc)?; - underlying.tmp_of = - Some(TmpConstruction::new(lhs_cvar, op, Some(rhs_cvar))); - + underlying.tmp_of = Some(TmpConstruction::new(lhs_cvar, op, Some(rhs_cvar))); + if let Some(ref mut dep_on) = underlying.dep_on { dep_on.push(rhs_cvar) } else { @@ -589,7 +588,8 @@ pub trait BinOp: AnalyzerBackend + Sized { Some(zero_node.into()), )), dep_on: { - let mut deps = tmp_rhs.dependent_on(self, true).into_expr_err(loc)?; + let mut deps = + tmp_rhs.dependent_on(self, true).into_expr_err(loc)?; deps.push(zero_node.into()); Some(deps) }, diff --git a/crates/solc-expressions/src/cmp.rs b/crates/solc-expressions/src/cmp.rs index b938617d..fe29b227 100644 --- a/crates/solc-expressions/src/cmp.rs +++ b/crates/solc-expressions/src/cmp.rs @@ -193,7 +193,8 @@ pub trait Cmp: AnalyzerBackend + Sized { .ref_range(self) .into_expr_err(loc)? .expect("No lhs range") - .exclusions.clone(); + .exclusions + .clone(); SolcRange::new(elem.clone(), elem, exclusions) }; diff --git a/crates/solc-expressions/src/context_builder/expr.rs b/crates/solc-expressions/src/context_builder/expr.rs index 15164aa5..d5e03f0e 100644 --- a/crates/solc-expressions/src/context_builder/expr.rs +++ b/crates/solc-expressions/src/context_builder/expr.rs @@ -7,7 +7,7 @@ use crate::{ use graph::{ elem::*, nodes::{Builtin, Concrete, ContextNode, ContextVar, ContextVarNode, ExprRet}, - AnalyzerBackend, ContextEdge, Edge, GraphBackend, Node, + AnalyzerBackend, ContextEdge, Edge, Node, }; use ethers_core::types::I256; @@ -330,8 +330,7 @@ pub trait ExpressionParser: fn delete_match( ctx: ContextNode, loc: &Loc, - analyzer: &mut (impl GraphBackend - + AnalyzerBackend), + analyzer: &mut impl AnalyzerBackend, ret: ExprRet, ) { match ret { diff --git a/crates/solc-expressions/src/context_builder/stmt.rs b/crates/solc-expressions/src/context_builder/stmt.rs index bee99471..85a6b170 100644 --- a/crates/solc-expressions/src/context_builder/stmt.rs +++ b/crates/solc-expressions/src/context_builder/stmt.rs @@ -35,7 +35,7 @@ pub trait StatementParser: &mut self, stmt: &Statement, unchecked: bool, - parent_ctx: Option + Clone + Copy>, + parent_ctx: Option + Copy>, ) where Self: Sized, { @@ -70,7 +70,7 @@ pub trait StatementParser: &mut self, stmt: &Statement, unchecked: bool, - parent_ctx: Option + Clone + Copy>, + parent_ctx: Option + Copy>, ) where Self: Sized, { diff --git a/crates/solc-expressions/src/env.rs b/crates/solc-expressions/src/env.rs index cba2736b..5795e670 100644 --- a/crates/solc-expressions/src/env.rs +++ b/crates/solc-expressions/src/env.rs @@ -273,7 +273,7 @@ pub trait Env: AnalyzerBackend + Sized { } }; let mut var = ContextVar::new_from_concrete(loc, ctx, node, self).into_expr_err(loc)?; - var.name = name.clone(); + var.name.clone_from(&name); var.display_name = name; var.is_tmp = false; var.is_symbolic = true; @@ -457,7 +457,7 @@ pub trait Env: AnalyzerBackend + Sized { }; let mut var = ContextVar::new_from_concrete(loc, ctx, node, self).into_expr_err(loc)?; - var.name = name.clone(); + var.name.clone_from(&name); var.display_name = name; var.is_tmp = false; var.is_symbolic = true; diff --git a/crates/solc-expressions/src/func_call/func_caller.rs b/crates/solc-expressions/src/func_call/func_caller.rs index 46c9b4f4..11090938 100644 --- a/crates/solc-expressions/src/func_call/func_caller.rs +++ b/crates/solc-expressions/src/func_call/func_caller.rs @@ -1,6 +1,5 @@ //! Traits & blanket implementations that facilitate performing various forms of function calls. -use crate::join::JoinStatTracker; use crate::{ func_call::join::FuncJoiner, func_call::modifier::ModifierCaller, helper::CallerHelper, internal_call::InternalFuncCaller, intrinsic_call::IntrinsicFuncCaller, @@ -67,9 +66,7 @@ impl<'a> NamedOrUnnamedArgs<'a> { pub fn parse( &self, - analyzer: &mut (impl AnalyzerBackend - + Sized - + GraphBackend), + analyzer: &mut (impl AnalyzerBackend + Sized), ctx: ContextNode, loc: Loc, ) -> Result<(), ExprErr> { @@ -101,9 +98,7 @@ impl<'a> NamedOrUnnamedArgs<'a> { pub fn parse_n( &self, n: usize, - analyzer: &mut (impl AnalyzerBackend - + Sized - + GraphBackend), + analyzer: &mut (impl AnalyzerBackend + Sized), ctx: ContextNode, loc: Loc, ) -> Result<(), ExprErr> { @@ -569,7 +564,7 @@ pub trait FuncCaller: var.name, ctx.new_tmp(analyzer).into_expr_err(loc)? ); - var.display_name = var.name.clone(); + var.display_name.clone_from(&var.name); } let node = analyzer.add_node(Node::ContextVar(var)); diff --git a/crates/solc-expressions/src/func_call/helper.rs b/crates/solc-expressions/src/func_call/helper.rs index 08b14019..ffae7ce9 100644 --- a/crates/solc-expressions/src/func_call/helper.rs +++ b/crates/solc-expressions/src/func_call/helper.rs @@ -7,7 +7,7 @@ use crate::{ use graph::{ nodes::{ CallFork, Context, ContextNode, ContextVar, ContextVarNode, ExprRet, FunctionNode, - FunctionParamNode, FunctionReturnNode, ModifierState, + FunctionParamNode, ModifierState, }, AnalyzerBackend, ContextEdge, Edge, Node, Range, VarType, }; @@ -45,7 +45,7 @@ pub trait CallerHelper: AnalyzerBackend + .cloned(); let mut new_cvar = self.add_if_err(res)?; new_cvar.loc = Some(param.loc(self).unwrap()); - new_cvar.name = name.clone(); + new_cvar.name.clone_from(&name); new_cvar.display_name = name; new_cvar.is_tmp = false; new_cvar.storage = if let Some(StorageLocation::Storage(_)) = @@ -441,7 +441,7 @@ pub trait CallerHelper: AnalyzerBackend + self.add_edge(cvar, callee_ctx, Edge::Context(ContextEdge::Return)); Ok(()) })?; - rets = callee_ctx.underlying(self).unwrap().ret.clone(); + rets.clone_from(&callee_ctx.underlying(self).unwrap().ret); } let target_rets = diff --git a/crates/solc-expressions/src/func_call/intrinsic_call/address.rs b/crates/solc-expressions/src/func_call/intrinsic_call/address.rs index 14cd80ec..0abe0230 100644 --- a/crates/solc-expressions/src/func_call/intrinsic_call/address.rs +++ b/crates/solc-expressions/src/func_call/intrinsic_call/address.rs @@ -21,9 +21,7 @@ pub trait AddressCaller: AnalyzerBackend + ctx: ContextNode, ) -> Result<(), ExprErr> { match &*func_name { - "delegatecall" | "staticcall" | "call" => { - self.external_call(&func_name, loc, ctx) - } + "delegatecall" | "staticcall" | "call" => self.external_call(&func_name, loc, ctx), "code" => { // TODO: try to be smarter based on the address input let bn = self.builtin_or_add(Builtin::DynamicBytes); @@ -56,19 +54,13 @@ pub trait AddressCaller: AnalyzerBackend + } } - fn external_call( - &mut self, - _ty: &str, - loc: Loc, - ctx: ContextNode, - ) -> Result<(), ExprErr> { + fn external_call(&mut self, _ty: &str, loc: Loc, ctx: ContextNode) -> Result<(), ExprErr> { // TODO: Check if we have the code for the address // if we dont, model it as a unrestricted call that can make other calls ctx.pop_expr_latest(loc, self).into_expr_err(loc)?; // TODO: try to be smarter based on the address input let booln = self.builtin_or_add(Builtin::Bool); - let bool_cvar = - ContextVar::new_from_builtin(loc, booln.into(), self).into_expr_err(loc)?; + let bool_cvar = ContextVar::new_from_builtin(loc, booln.into(), self).into_expr_err(loc)?; let bool_node = self.add_node(Node::ContextVar(bool_cvar)); ctx.add_var(bool_node.into(), self).into_expr_err(loc)?; self.add_edge(bool_node, ctx, Edge::Context(ContextEdge::Variable)); diff --git a/crates/solc-expressions/src/func_call/intrinsic_call/types.rs b/crates/solc-expressions/src/func_call/intrinsic_call/types.rs index 9bc1fff7..73950491 100644 --- a/crates/solc-expressions/src/func_call/intrinsic_call/types.rs +++ b/crates/solc-expressions/src/func_call/intrinsic_call/types.rs @@ -1,12 +1,12 @@ -use crate::ListAccess; use crate::func_caller::NamedOrUnnamedArgs; +use crate::ListAccess; use crate::{variable::Variable, ContextBuilder, ExprErr, ExpressionParser, IntoExprErr}; use graph::nodes::FunctionNode; use graph::{ elem::*, nodes::{BuiltInNode, Builtin, ContextNode, ContextVar, ContextVarNode, ExprRet, TyNode}, - AnalyzerBackend, GraphBackend, Node, Range, VarType, + AnalyzerBackend, Node, Range, VarType, }; use shared::NodeIdx; @@ -154,7 +154,7 @@ pub trait TypesCaller: AnalyzerBackend + S fn cast_match( ctx: ContextNode, loc: Loc, - analyzer: &mut (impl GraphBackend + AnalyzerBackend + ListAccess), + analyzer: &mut impl ListAccess, ty: &Builtin, ret: ExprRet, func_idx: NodeIdx, @@ -168,7 +168,6 @@ pub trait TypesCaller: AnalyzerBackend + S .as_cast_tmp(loc, ctx, ty.clone(), analyzer) .into_expr_err(loc)?; - let v_ty = VarType::try_from_idx(analyzer, func_idx).expect(""); let maybe_new_range = cvar.cast_exprs(&v_ty, analyzer).into_expr_err(loc)?; new_var.underlying_mut(analyzer).into_expr_err(loc)?.ty = v_ty; @@ -184,7 +183,13 @@ pub trait TypesCaller: AnalyzerBackend + S if cvar.is_indexable(analyzer).into_expr_err(loc)? { // input is indexable. get the length attribute, create a new length for the casted type - let _ = analyzer.create_length(ctx, loc, cvar, new_var.latest_version(analyzer), false)?; + let _ = analyzer.create_length( + ctx, + loc, + cvar, + new_var.latest_version(analyzer), + false, + )?; } ctx.push_expr(ExprRet::Single(new_var.into()), analyzer) diff --git a/crates/solc-expressions/src/func_call/join.rs b/crates/solc-expressions/src/func_call/join.rs index adb03fcc..3724f8b2 100644 --- a/crates/solc-expressions/src/func_call/join.rs +++ b/crates/solc-expressions/src/func_call/join.rs @@ -1,15 +1,14 @@ -use graph::AsDotStr; -use graph::SolcRange; -use shared::AnalyzerLike; -use graph::nodes::Concrete; -use shared::NodeIdx; use crate::member_access::ListAccess; use crate::{helper::CallerHelper, ExprErr, IntoExprErr}; use graph::elem::Elem; use graph::elem::RangeElem; +use graph::nodes::Concrete; use graph::nodes::ContextVar; use graph::Range; +use graph::SolcRange; use graph::VarType; +use shared::AnalyzerLike; +use shared::NodeIdx; use shared::StorageLocation; use graph::{ @@ -22,7 +21,11 @@ use solang_parser::pt::{Expression, Loc}; use std::collections::BTreeMap; impl FuncJoiner for T where - T: AnalyzerBackend + Sized + GraphBackend + CallerHelper + JoinStatTracker + T: AnalyzerBackend + + Sized + + GraphBackend + + CallerHelper + + JoinStatTracker { } /// A trait for calling a function @@ -38,7 +41,10 @@ pub trait FuncJoiner: params: &[FunctionParamNode], func_inputs: &[ContextVarNode], ) -> Result { - tracing::trace!("Trying to join function: {}", func.name(self).into_expr_err(loc)?); + tracing::trace!( + "Trying to join function: {}", + func.name(self).into_expr_err(loc)? + ); // ensure no modifiers (for now) // if pure function: // grab requirements for context @@ -58,8 +64,12 @@ pub trait FuncJoiner: { let edges = body_ctx.successful_edges(self).into_expr_err(loc)?; if edges.len() == 1 { - tracing::trace!("Joining function: {}", func.name(self).into_expr_err(loc)?); - let replacement_map = self.basic_inputs_replacement_map(body_ctx, loc, params, func_inputs)?; + tracing::trace!( + "Joining function: {}", + func.name(self).into_expr_err(loc)? + ); + let replacement_map = + self.basic_inputs_replacement_map(body_ctx, loc, params, func_inputs)?; let mut rets: Vec<_> = edges[0] .return_nodes(self) .into_expr_err(loc)? @@ -68,10 +78,11 @@ pub trait FuncJoiner: .map(|(i, (_, ret_node))| { let mut new_var = ret_node.underlying(self).unwrap().clone(); let new_name = format!("{}.{i}", func.name(self).unwrap()); - new_var.name = new_name.clone(); + new_var.name.clone_from(&new_name); new_var.display_name = new_name; if let Some(mut range) = new_var.ty.take_range() { - let mut range: SolcRange = range.take_flattened_range(self).unwrap().into(); + let mut range: SolcRange = + range.take_flattened_range(self).unwrap().into(); replacement_map.iter().for_each(|(replace, replacement)| { range.replace_dep(*replace, replacement.0.clone(), self); }); @@ -83,7 +94,9 @@ pub trait FuncJoiner: if let Some(ref mut dep_on) = &mut new_var.dep_on { dep_on.iter_mut().for_each(|d| { - if let Some((_, r)) = replacement_map.get(&(*d).into()) { *d = *r } + if let Some((_, r)) = replacement_map.get(&(*d).into()) { + *d = *r + } }); } @@ -94,15 +107,29 @@ pub trait FuncJoiner: if let Ok(fields) = ret_node.struct_to_fields(self) { if !fields.is_empty() { fields.iter().for_each(|field| { - let mut new_var = field.underlying(self).unwrap().clone(); - let new_name = format!("{}.{i}.{}", func.name(self).unwrap(), field.name(self).unwrap()); - new_var.name = new_name.clone(); + let mut new_var = + field.underlying(self).unwrap().clone(); + let new_name = format!( + "{}.{i}.{}", + func.name(self).unwrap(), + field.name(self).unwrap() + ); + new_var.name.clone_from(&new_name); new_var.display_name = new_name; if let Some(mut range) = new_var.ty.take_range() { - let mut range: SolcRange = range.take_flattened_range(self).unwrap().into(); - replacement_map.iter().for_each(|(replace, replacement)| { - range.replace_dep(*replace, replacement.0.clone(), self); - }); + let mut range: SolcRange = range + .take_flattened_range(self) + .unwrap() + .into(); + replacement_map.iter().for_each( + |(replace, replacement)| { + range.replace_dep( + *replace, + replacement.0.clone(), + self, + ); + }, + ); range.cache_eval(self).unwrap(); @@ -111,16 +138,25 @@ pub trait FuncJoiner: if let Some(ref mut dep_on) = &mut new_var.dep_on { dep_on.iter_mut().for_each(|d| { - if let Some((_, r)) = replacement_map.get(&(*d).into()) { *d = *r } + if let Some((_, r)) = + replacement_map.get(&(*d).into()) + { + *d = *r + } }); } - let new_field = - ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); - self.add_edge(new_field, new_cvar, Edge::Context(ContextEdge::AttrAccess("field"))); + let new_field = ContextVarNode::from( + self.add_node(Node::ContextVar(new_var)), + ); + self.add_edge( + new_field, + new_cvar, + Edge::Context(ContextEdge::AttrAccess("field")), + ); }); } } - + self.add_edge(new_cvar, ctx, Edge::Context(ContextEdge::Variable)); ctx.add_var(new_cvar, self).unwrap(); ExprRet::Single(new_cvar.into()) @@ -133,7 +169,8 @@ pub trait FuncJoiner: .try_for_each(|dep| { let mut new_var = dep.underlying(self)?.clone(); if let Some(mut range) = new_var.ty.take_range() { - let mut range: SolcRange = range.take_flattened_range(self).unwrap().into(); + let mut range: SolcRange = + range.take_flattened_range(self).unwrap().into(); replacement_map.iter().for_each(|(replace, replacement)| { range.replace_dep(*replace, replacement.0.clone(), self); }); @@ -144,7 +181,9 @@ pub trait FuncJoiner: if let Some(ref mut dep_on) = &mut new_var.dep_on { dep_on.iter_mut().for_each(|d| { - if let Some((_, r)) = replacement_map.get(&(*d).into()) { *d = *r } + if let Some((_, r)) = replacement_map.get(&(*d).into()) { + *d = *r + } }); } let new_cvar = @@ -152,22 +191,20 @@ pub trait FuncJoiner: self.add_edge(new_cvar, ctx, Edge::Context(ContextEdge::Variable)); ctx.add_var(new_cvar, self)?; ctx.add_ctx_dep(new_cvar, self) - }).into_expr_err(loc)?; - - func.returns(self) - .to_vec() - .into_iter() - .for_each(|ret| { - if let Some(var) = ContextVar::maybe_new_from_func_ret( - self, - ret.underlying(self).unwrap().clone(), - ) { - let cvar = self.add_node(Node::ContextVar(var)); - ctx.add_var(cvar.into(), self).unwrap(); - self.add_edge(cvar, ctx, Edge::Context(ContextEdge::Variable)); - rets.push(ExprRet::Single(cvar)); - } - }); + }) + .into_expr_err(loc)?; + + func.returns(self).to_vec().into_iter().for_each(|ret| { + if let Some(var) = ContextVar::maybe_new_from_func_ret( + self, + ret.underlying(self).unwrap().clone(), + ) { + let cvar = self.add_node(Node::ContextVar(var)); + ctx.add_var(cvar.into(), self).unwrap(); + self.add_edge(cvar, ctx, Edge::Context(ContextEdge::Variable)); + rets.push(ExprRet::Single(cvar)); + } + }); ctx.underlying_mut(self).into_expr_err(loc)?.path = format!( "{}.{}.resume{{ {} }}", @@ -179,12 +216,19 @@ pub trait FuncJoiner: .into_expr_err(loc)?; self.add_completed_pure(true, false, false, edges[0]); } else { - tracing::trace!("Branching pure join function: {}", func.name(self).into_expr_err(loc)?); + tracing::trace!( + "Branching pure join function: {}", + func.name(self).into_expr_err(loc)? + ); self.add_completed_pure(false, false, true, body_ctx); } } else { - tracing::trace!("Childless pure join: {}", func.name(self).into_expr_err(loc)?); - let replacement_map = self.basic_inputs_replacement_map(body_ctx, loc, params, func_inputs)?; + tracing::trace!( + "Childless pure join: {}", + func.name(self).into_expr_err(loc)? + ); + let replacement_map = + self.basic_inputs_replacement_map(body_ctx, loc, params, func_inputs)?; // 1. Create a new variable with name `.` // 2. Set the range to be the copy of the return's simplified range from the function // 3. Replace the fundamentals with the input data @@ -196,10 +240,11 @@ pub trait FuncJoiner: .map(|(i, (_, ret_node))| { let mut new_var = ret_node.underlying(self).unwrap().clone(); let new_name = format!("{}.{i}", func.name(self).unwrap()); - new_var.name = new_name.clone(); + new_var.name.clone_from(&new_name); new_var.display_name = new_name; if let Some(mut range) = new_var.ty.take_range() { - let mut range: SolcRange = range.take_flattened_range(self).unwrap().into(); + let mut range: SolcRange = + range.take_flattened_range(self).unwrap().into(); replacement_map.iter().for_each(|(replace, replacement)| { range.replace_dep(*replace, replacement.0.clone(), self); }); @@ -211,7 +256,9 @@ pub trait FuncJoiner: if let Some(ref mut dep_on) = &mut new_var.dep_on { dep_on.iter_mut().for_each(|d| { - if let Some((_, r)) = replacement_map.get(&(*d).into()) { *d = *r } + if let Some((_, r)) = replacement_map.get(&(*d).into()) { + *d = *r + } }); } @@ -225,14 +272,25 @@ pub trait FuncJoiner: if !fields.is_empty() { fields.iter().for_each(|field| { let mut new_var = field.underlying(self).unwrap().clone(); - let new_name = format!("{}.{i}.{}", func.name(self).unwrap(), field.name(self).unwrap()); - new_var.name = new_name.clone(); + let new_name = format!( + "{}.{i}.{}", + func.name(self).unwrap(), + field.name(self).unwrap() + ); + new_var.name.clone_from(&new_name); new_var.display_name = new_name; if let Some(mut range) = new_var.ty.take_range() { - let mut range: SolcRange = range.take_flattened_range(self).unwrap().into(); - replacement_map.iter().for_each(|(replace, replacement)| { - range.replace_dep(*replace, replacement.0.clone(), self); - }); + let mut range: SolcRange = + range.take_flattened_range(self).unwrap().into(); + replacement_map.iter().for_each( + |(replace, replacement)| { + range.replace_dep( + *replace, + replacement.0.clone(), + self, + ); + }, + ); range.cache_eval(self).unwrap(); @@ -241,12 +299,21 @@ pub trait FuncJoiner: if let Some(ref mut dep_on) = &mut new_var.dep_on { dep_on.iter_mut().for_each(|d| { - if let Some((_, r)) = replacement_map.get(&(*d).into()) { *d = *r } + if let Some((_, r)) = + replacement_map.get(&(*d).into()) + { + *d = *r + } }); } - let new_field = - ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); - self.add_edge(new_field, new_cvar, Edge::Context(ContextEdge::AttrAccess("field"))); + let new_field = ContextVarNode::from( + self.add_node(Node::ContextVar(new_var)), + ); + self.add_edge( + new_field, + new_cvar, + Edge::Context(ContextEdge::AttrAccess("field")), + ); }); } } @@ -263,7 +330,8 @@ pub trait FuncJoiner: .try_for_each(|dep| { let mut new_var = dep.underlying(self)?.clone(); if let Some(mut range) = new_var.ty.take_range() { - let mut range: SolcRange = range.take_flattened_range(self).unwrap().into(); + let mut range: SolcRange = + range.take_flattened_range(self).unwrap().into(); replacement_map.iter().for_each(|(replace, replacement)| { range.replace_dep(*replace, replacement.0.clone(), self); }); @@ -275,10 +343,11 @@ pub trait FuncJoiner: // TODO: the naming isn't correct here and we move variables around // in a dumb way - if let Some(ref mut dep_on) = &mut new_var.dep_on { dep_on.iter_mut().for_each(|d| { - if let Some((_, r)) = replacement_map.get(&(*d).into()) { *d = *r } + if let Some((_, r)) = replacement_map.get(&(*d).into()) { + *d = *r + } }); } @@ -288,22 +357,20 @@ pub trait FuncJoiner: self.add_edge(new_cvar, ctx, Edge::Context(ContextEdge::Variable)); ctx.add_var(new_cvar, self)?; ctx.add_ctx_dep(new_cvar, self) - }).into_expr_err(loc)?; + }) + .into_expr_err(loc)?; - func.returns(self) - .to_vec() - .into_iter() - .for_each(|ret| { - if let Some(var) = ContextVar::maybe_new_from_func_ret( - self, - ret.underlying(self).unwrap().clone(), - ) { - let cvar = self.add_node(Node::ContextVar(var)); - ctx.add_var(cvar.into(), self).unwrap(); - self.add_edge(cvar, ctx, Edge::Context(ContextEdge::Variable)); - rets.push(ExprRet::Single(cvar)); - } - }); + func.returns(self).to_vec().into_iter().for_each(|ret| { + if let Some(var) = ContextVar::maybe_new_from_func_ret( + self, + ret.underlying(self).unwrap().clone(), + ) { + let cvar = self.add_node(Node::ContextVar(var)); + ctx.add_var(cvar.into(), self).unwrap(); + self.add_edge(cvar, ctx, Edge::Context(ContextEdge::Variable)); + rets.push(ExprRet::Single(cvar)); + } + }); ctx.underlying_mut(self).into_expr_err(loc)?.path = format!( "{}.{}.resume{{ {} }}", @@ -327,18 +394,27 @@ pub trait FuncJoiner: { let edges = body_ctx.successful_edges(self).into_expr_err(loc)?; if edges.len() == 1 { - tracing::trace!("View join function: {}", func.name(self).into_expr_err(loc)?); + tracing::trace!( + "View join function: {}", + func.name(self).into_expr_err(loc)? + ); self.add_completed_view(false, false, false, body_ctx); } else { - tracing::trace!("Branching view join function: {}", func.name(self).into_expr_err(loc)?); + tracing::trace!( + "Branching view join function: {}", + func.name(self).into_expr_err(loc)? + ); self.add_completed_view(false, false, true, body_ctx); } } else { - tracing::trace!("Childless view join function: {}", func.name(self).into_expr_err(loc)?); + tracing::trace!( + "Childless view join function: {}", + func.name(self).into_expr_err(loc)? + ); self.add_completed_view(false, true, false, body_ctx); } } - } else if let Some(body_ctx) = func.maybe_body_ctx(self) { + } else if let Some(body_ctx) = func.maybe_body_ctx(self) { if body_ctx .underlying(self) .into_expr_err(loc)? @@ -350,11 +426,17 @@ pub trait FuncJoiner: tracing::trace!("Mut join function: {}", func.name(self).into_expr_err(loc)?); self.add_completed_mut(false, false, false, body_ctx); } else { - tracing::trace!("Branching mut join function: {}", func.name(self).into_expr_err(loc)?); + tracing::trace!( + "Branching mut join function: {}", + func.name(self).into_expr_err(loc)? + ); self.add_completed_mut(false, false, true, body_ctx); } } else { - tracing::trace!("Childless mut join function: {}", func.name(self).into_expr_err(loc)?); + tracing::trace!( + "Childless mut join function: {}", + func.name(self).into_expr_err(loc)? + ); self.add_completed_mut(false, true, false, body_ctx); } } @@ -370,7 +452,8 @@ pub trait FuncJoiner: func_inputs: &[ContextVarNode], ) -> Result, ContextVarNode)>, ExprErr> { let inputs = ctx.input_variables(self); - let mut replacement_map: BTreeMap, ContextVarNode)> = BTreeMap::default(); + let mut replacement_map: BTreeMap, ContextVarNode)> = + BTreeMap::default(); params .iter() .zip(func_inputs.iter()) @@ -402,9 +485,7 @@ pub trait FuncJoiner: Edge::Context(ContextEdge::InputVariable), ); - if let Some(param_ty) = - VarType::try_from_idx(self, param.ty(self).unwrap()) - { + if let Some(param_ty) = VarType::try_from_idx(self, param.ty(self).unwrap()) { if !replacement.ty_eq_ty(¶m_ty, self).into_expr_err(loc)? { replacement .cast_from_ty(param_ty, self) @@ -420,14 +501,8 @@ pub trait FuncJoiner: if let (Some(r), Some(r2)) = (replacement.range(self).unwrap(), param.range(self).unwrap()) { - let new_min = r - .range_min() - .into_owned() - .cast(r2.range_min().into_owned()); - let new_max = r - .range_max() - .into_owned() - .cast(r2.range_max().into_owned()); + let new_min = r.range_min().into_owned().cast(r2.range_min().into_owned()); + let new_max = r.range_max().into_owned().cast(r2.range_max().into_owned()); replacement .latest_version(self) .try_set_range_min(self, new_min) @@ -443,12 +518,7 @@ pub trait FuncJoiner: } ctx.add_var(replacement, self).unwrap(); - self.add_edge( - replacement, - ctx, - Edge::Context(ContextEdge::Variable), - ); - + self.add_edge(replacement, ctx, Edge::Context(ContextEdge::Variable)); let Some(correct_input) = inputs .iter() @@ -465,18 +535,29 @@ pub trait FuncJoiner: let replacement_fields = func_input.struct_to_fields(self).unwrap(); fields.iter().for_each(|field| { let field_name = field.name(self).unwrap(); - let to_replace_field_name = field_name.split('.').collect::>()[1]; - if let Some(replacement_field) = replacement_fields.iter().find(|replacement_field| { - let name = replacement_field.name(self).unwrap(); - let replacement_name = name.split('.').collect::>()[1]; - to_replace_field_name == replacement_name - }) { - let mut replacement_field_as_elem = Elem::from(*replacement_field); + let to_replace_field_name = + field_name.split('.').collect::>()[1]; + if let Some(replacement_field) = + replacement_fields.iter().find(|replacement_field| { + let name = replacement_field.name(self).unwrap(); + let replacement_name = + name.split('.').collect::>()[1]; + to_replace_field_name == replacement_name + }) + { + let mut replacement_field_as_elem = + Elem::from(*replacement_field); replacement_field_as_elem.arenaize(self).unwrap(); if let Some(next) = field.next_version(self) { - replacement_map.insert(next.0.into(), (replacement_field_as_elem.clone(), *replacement_field)); + replacement_map.insert( + next.0.into(), + (replacement_field_as_elem.clone(), *replacement_field), + ); } - replacement_map.insert(field.0.into(), (replacement_field_as_elem, *replacement_field)); + replacement_map.insert( + field.0.into(), + (replacement_field_as_elem, *replacement_field), + ); } }); } @@ -486,9 +567,11 @@ pub trait FuncJoiner: replacement_as_elem.arenaize(self).into_expr_err(loc)?; if let Some(next) = correct_input.next_version(self) { - replacement_map.insert(next.0.into(), (replacement_as_elem.clone(), replacement)); + replacement_map + .insert(next.0.into(), (replacement_as_elem.clone(), replacement)); } - replacement_map.insert(correct_input.0.into(), (replacement_as_elem, replacement)); + replacement_map + .insert(correct_input.0.into(), (replacement_as_elem, replacement)); } Ok(()) })?; @@ -496,13 +579,18 @@ pub trait FuncJoiner: } } -impl JoinStatTracker for T where - T: AnalyzerLike + GraphBackend -{ -} +impl JoinStatTracker for T where T: AnalyzerLike + GraphBackend {} pub trait JoinStatTracker: AnalyzerLike { - fn add_completed_pure(&mut self, completed: bool, no_children: bool, forks: bool, target_ctx: ContextNode) where Self: Sized + GraphBackend { + fn add_completed_pure( + &mut self, + completed: bool, + no_children: bool, + forks: bool, + target_ctx: ContextNode, + ) where + Self: Sized + GraphBackend, + { match (no_children, forks) { (true, _) => { let num_vars = target_ctx.vars(self).len(); @@ -535,10 +623,18 @@ pub trait JoinStatTracker: AnalyzerLike { stats.pure_children_forks_joins.completed_joins += 1; } } - } + } } - fn add_completed_view(&mut self, completed: bool, no_children: bool, forks: bool, target_ctx: ContextNode) where Self: Sized + GraphBackend { + fn add_completed_view( + &mut self, + completed: bool, + no_children: bool, + forks: bool, + target_ctx: ContextNode, + ) where + Self: Sized + GraphBackend, + { match (no_children, forks) { (true, _) => { let num_vars = target_ctx.vars(self).len(); @@ -572,10 +668,18 @@ pub trait JoinStatTracker: AnalyzerLike { stats.view_children_forks_joins.completed_joins += 1; } } - } + } } - fn add_completed_mut(&mut self, completed: bool, no_children: bool, forks: bool, target_ctx: ContextNode) where Self: Sized + GraphBackend { + fn add_completed_mut( + &mut self, + completed: bool, + no_children: bool, + forks: bool, + target_ctx: ContextNode, + ) where + Self: Sized + GraphBackend, + { match (no_children, forks) { (true, _) => { let num_vars = target_ctx.vars(self).len(); @@ -600,6 +704,6 @@ pub trait JoinStatTracker: AnalyzerLike { stats.mut_children_forks_joins.completed_joins += 1; } } - } + } } -} \ No newline at end of file +} diff --git a/crates/solc-expressions/src/member_access/builtin_access.rs b/crates/solc-expressions/src/member_access/builtin_access.rs index d645d4f1..3ea01028 100644 --- a/crates/solc-expressions/src/member_access/builtin_access.rs +++ b/crates/solc-expressions/src/member_access/builtin_access.rs @@ -1,4 +1,3 @@ -use crate::func_call::intrinsic_call::AddressCaller; use crate::{ExprErr, IntoExprErr, LibraryAccess}; use graph::{ @@ -213,7 +212,7 @@ pub trait BuiltinAccess: let mut var = ContextVar::new_from_concrete(loc, ctx, node, self) .into_expr_err(loc)?; var.name = format!("int{size}.max"); - var.display_name = var.name.clone(); + var.display_name.clone_from(&var.name); var.is_tmp = true; var.is_symbolic = false; let cvar = self.add_node(Node::ContextVar(var)); @@ -228,7 +227,7 @@ pub trait BuiltinAccess: let mut var = ContextVar::new_from_concrete(loc, ctx, node, self) .into_expr_err(loc)?; var.name = format!("int{size}.min"); - var.display_name = var.name.clone(); + var.display_name.clone_from(&var.name); var.is_tmp = true; var.is_symbolic = false; let cvar = self.add_node(Node::ContextVar(var)); @@ -257,7 +256,7 @@ pub trait BuiltinAccess: let mut var = ContextVar::new_from_concrete(loc, ctx, node, self) .into_expr_err(loc)?; var.name = format!("uint{size}.max"); - var.display_name = var.name.clone(); + var.display_name.clone_from(&var.name); var.is_tmp = true; var.is_symbolic = false; let cvar = self.add_node(Node::ContextVar(var)); @@ -272,7 +271,7 @@ pub trait BuiltinAccess: let mut var = ContextVar::new_from_concrete(loc, ctx, node, self) .into_expr_err(loc)?; var.name = format!("uint{size}.min"); - var.display_name = var.name.clone(); + var.display_name.clone_from(&var.name); var.is_tmp = true; var.is_symbolic = false; let cvar = self.add_node(Node::ContextVar(var)); diff --git a/crates/solc-expressions/src/require.rs b/crates/solc-expressions/src/require.rs index bd1ad4a1..bb63e629 100644 --- a/crates/solc-expressions/src/require.rs +++ b/crates/solc-expressions/src/require.rs @@ -520,8 +520,11 @@ pub trait Require: AnalyzerBackend + Variable + BinOp + Sized { Some(rhs_cvar), )), dep_on: { - let mut deps = lhs_cvar.dependent_on(analyzer, true).into_expr_err(loc)?; - deps.extend(rhs_cvar.dependent_on(analyzer, true).into_expr_err(loc)?); + let mut deps = + lhs_cvar.dependent_on(analyzer, true).into_expr_err(loc)?; + deps.extend( + rhs_cvar.dependent_on(analyzer, true).into_expr_err(loc)?, + ); Some(deps) }, ty: VarType::BuiltIn( @@ -857,7 +860,11 @@ pub trait Require: AnalyzerBackend + Variable + BinOp + Sized { )), dep_on: { let mut deps = tmp_true.dependent_on(self, true).into_expr_err(loc)?; - deps.extend(conditional_cvar.dependent_on(self, true).into_expr_err(loc)?); + deps.extend( + conditional_cvar + .dependent_on(self, true) + .into_expr_err(loc)?, + ); Some(deps) }, is_symbolic: new_lhs.is_symbolic(self).into_expr_err(loc)? @@ -1051,8 +1058,12 @@ pub trait Require: AnalyzerBackend + Variable + BinOp + Sized { } // we add one to the element because its strict > - let Some(max_conc) = const_var.evaled_range_min(self).unwrap().unwrap().maybe_concrete() - else { + let Some(max_conc) = const_var + .evaled_range_min(self) + .unwrap() + .unwrap() + .maybe_concrete() + else { return Err(ExprErr::BadRange(loc, format!( "Expected {} to have a concrete range by now. This is likely a bug (update nonconst from const: Gt). Max: {}, expr: {} {} {}, const value: {}", nonconst_var.display_name(self).unwrap(),