From b703c005911959ce2e5c7f6a4bbaf7325354b815 Mon Sep 17 00:00:00 2001 From: brock elmore Date: Mon, 18 Mar 2024 14:49:33 -0700 Subject: [PATCH] perf --- crates/graph/src/nodes/context/var/node.rs | 83 +++++++++++++------ .../graph/src/nodes/context/var/underlying.rs | 14 ++++ crates/graph/src/nodes/var_ty.rs | 1 + crates/graph/src/range/elem/elem_enum.rs | 5 +- crates/solc-expressions/src/array.rs | 5 ++ crates/solc-expressions/src/assign.rs | 7 ++ crates/solc-expressions/src/bin_op.rs | 21 ++++- crates/solc-expressions/src/cmp.rs | 6 ++ .../func_call/intrinsic_call/constructors.rs | 2 + crates/solc-expressions/src/func_call/join.rs | 72 +++++++++++++--- crates/solc-expressions/src/list.rs | 2 + .../src/member_access/list_access.rs | 2 + crates/solc-expressions/src/require.rs | 15 ++++ crates/solc-expressions/src/variable.rs | 2 + .../solc-expressions/src/yul/yul_builder.rs | 2 + 15 files changed, 199 insertions(+), 40 deletions(-) diff --git a/crates/graph/src/nodes/context/var/node.rs b/crates/graph/src/nodes/context/var/node.rs index 967fad60..5284127e 100644 --- a/crates/graph/src/nodes/context/var/node.rs +++ b/crates/graph/src/nodes/context/var/node.rs @@ -309,41 +309,74 @@ impl ContextVarNode { .collect() } - pub fn dependent_on( + pub fn set_dependent_on( &self, - analyzer: &impl GraphBackend, - return_self: bool, - ) -> Result, GraphError> { - self.dependent_on_no_recursion(analyzer, &mut vec![*self], return_self) + analyzer: &mut impl GraphBackend, + ) -> Result<(), GraphError> { + let mut return_self = false; + let mut first_iter = true; + let mut stack = vec![*self]; + let mut result = vec![]; + + while let Some(node) = stack.pop() { + if result.contains(&node) { + continue; + } + + let underlying = node.underlying(analyzer)?; + if let Some(tmp) = underlying.tmp_of() { + stack.push(tmp.lhs); + if let Some(rhs) = tmp.rhs { + stack.push(rhs); + } + } else if return_self { + result.push(node); + } + + if first_iter { + first_iter = false; + return_self = true; + } + } + + self.underlying_mut(analyzer)?.dep_on = Some(result); + Ok(()) } - fn dependent_on_no_recursion( + pub fn dependent_on( &self, analyzer: &impl GraphBackend, - seen: &mut Vec, - return_self: bool, + mut return_self: bool, ) -> Result, GraphError> { - let underlying = self.underlying(analyzer)?; - if let Some(tmp) = underlying.tmp_of() { - let mut nodes = if !seen.contains(&tmp.lhs) { - seen.push(tmp.lhs); - tmp.lhs.dependent_on(analyzer, true)? - } else { - vec![] - }; + if let Some(dep_on) = &self.underlying(analyzer)?.dep_on { + return Ok(dep_on.to_vec()); + } + let mut first_iter = true; + let mut stack = vec![*self]; + let mut result = vec![]; - if let Some(rhs) = tmp.rhs { - if !seen.contains(&rhs) { - seen.push(rhs); - nodes.extend(rhs.dependent_on(analyzer, true)?); + while let Some(node) = stack.pop() { + if result.contains(&node) { + continue; + } + + let underlying = node.underlying(analyzer)?; + if let Some(tmp) = underlying.tmp_of() { + stack.push(tmp.lhs); + if let Some(rhs) = tmp.rhs { + stack.push(rhs); } + } else if return_self { + result.push(node); + } + + if first_iter { + first_iter = false; + return_self = true; } - Ok(nodes) - } else if return_self { - Ok(vec![*self]) - } else { - Ok(vec![]) } + + Ok(result) } pub fn graph_dependent_on( diff --git a/crates/graph/src/nodes/context/var/underlying.rs b/crates/graph/src/nodes/context/var/underlying.rs index 76a29932..500ceda3 100644 --- a/crates/graph/src/nodes/context/var/underlying.rs +++ b/crates/graph/src/nodes/context/var/underlying.rs @@ -20,6 +20,7 @@ pub struct ContextVar { pub storage: Option, pub is_tmp: bool, pub tmp_of: Option, + pub dep_on: Option>, pub is_symbolic: bool, pub is_return: bool, pub ty: VarType, @@ -76,6 +77,7 @@ impl ContextVar { storage: None, is_tmp: true, tmp_of: None, + dep_on: None, is_symbolic: false, is_return: false, ty: VarType::Concrete(concrete_node), @@ -128,6 +130,7 @@ impl ContextVar { storage: None, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: VarType::User( @@ -154,6 +157,7 @@ impl ContextVar { storage: Some(StorageLocation::Memory(Loc::Implicit)), is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: VarType::User(TypeNode::Struct(struct_node), None), @@ -177,6 +181,7 @@ impl ContextVar { storage: Some(StorageLocation::Memory(Loc::Implicit)), is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: VarType::try_from_idx(analyzer, ty_node.0.into()).unwrap(), @@ -195,6 +200,7 @@ impl ContextVar { storage: None, is_tmp: true, tmp_of: None, + dep_on: None, is_symbolic: false, is_return: false, ty: VarType::try_from_idx(analyzer, bn_node.into()).unwrap(), @@ -490,6 +496,7 @@ impl ContextVar { storage, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty, @@ -517,6 +524,7 @@ impl ContextVar { storage: parent_var.storage, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty, @@ -541,6 +549,7 @@ impl ContextVar { storage: None, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: VarType::User( @@ -566,6 +575,7 @@ impl ContextVar { storage: Some(parent_storage), is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: index.underlying(analyzer)?.is_symbolic, is_return: false, ty: parent_var.dynamic_underlying_ty(analyzer)?, @@ -583,6 +593,7 @@ impl ContextVar { storage: None, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: false, is_return: false, ty: VarType::User(TypeNode::Func(func), None), @@ -602,6 +613,7 @@ impl ContextVar { storage: param.storage, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty, @@ -627,6 +639,7 @@ impl ContextVar { storage: ret.storage, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: true, ty, @@ -658,6 +671,7 @@ impl ContextVar { storage: ret.storage, is_tmp, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: true, ty, diff --git a/crates/graph/src/nodes/var_ty.rs b/crates/graph/src/nodes/var_ty.rs index 6503713e..7faeaf02 100644 --- a/crates/graph/src/nodes/var_ty.rs +++ b/crates/graph/src/nodes/var_ty.rs @@ -146,6 +146,7 @@ impl VarNode { display_name: self.name(analyzer)?, storage: None, is_tmp: false, + dep_on: None, tmp_of: None, is_symbolic: true, is_return: false, diff --git a/crates/graph/src/range/elem/elem_enum.rs b/crates/graph/src/range/elem/elem_enum.rs index a34d292a..d35671a4 100644 --- a/crates/graph/src/range/elem/elem_enum.rs +++ b/crates/graph/src/range/elem/elem_enum.rs @@ -348,8 +348,9 @@ impl Elem { }, Elem::Null => {} Elem::Arena(_) => { - let s = self.dearenaize(analyzer).clone(); - s.borrow_mut().replace_dep(to_replace, replacement, analyzer); + let mut s = self.dearenaize(analyzer).borrow().clone(); + s.replace_dep(to_replace, replacement, analyzer); + *self = Elem::Arena(analyzer.range_arena_idx_or_upsert(s)); } } } diff --git a/crates/solc-expressions/src/array.rs b/crates/solc-expressions/src/array.rs index a7994193..f0412805 100644 --- a/crates/solc-expressions/src/array.rs +++ b/crates/solc-expressions/src/array.rs @@ -209,6 +209,11 @@ pub trait Array: AnalyzerBackend + Sized { RangeOp::SetIndices, Some(index), )), + dep_on: { + let mut deps = parent.dependent_on(self, true).into_expr_err(loc)?; + deps.extend(index.dependent_on(self, true).into_expr_err(loc)?); + Some(deps) + }, is_symbolic: true, is_return: false, ty, diff --git a/crates/solc-expressions/src/assign.rs b/crates/solc-expressions/src/assign.rs index 85fdd179..567fec7c 100644 --- a/crates/solc-expressions/src/assign.rs +++ b/crates/solc-expressions/src/assign.rs @@ -144,6 +144,13 @@ pub trait Assign: AnalyzerBackend + Sized 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 { + dep_on.push(rhs_cvar) + } else { + new_lhs.set_dependent_on(self).into_expr_err(loc)?; + } + if lhs_cvar.is_storage(self).into_expr_err(loc)? { self.add_edge(new_lhs, rhs_cvar, Edge::Context(ContextEdge::StorageWrite)); } diff --git a/crates/solc-expressions/src/bin_op.rs b/crates/solc-expressions/src/bin_op.rs index ba084aaf..27d0924c 100644 --- a/crates/solc-expressions/src/bin_op.rs +++ b/crates/solc-expressions/src/bin_op.rs @@ -163,8 +163,16 @@ pub trait BinOp: AnalyzerBackend + Sized { let new_lhs = if assign { let new = self.advance_var_in_ctx_forcible(lhs_cvar, loc, ctx, true)?; - new.underlying_mut(self).into_expr_err(loc)?.tmp_of = + let underlying = new.underlying_mut(self).into_expr_err(loc)?; + 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 { + new.set_dependent_on(self).into_expr_err(loc)?; + } + new } else { let mut new_lhs_underlying = ContextVar { @@ -188,6 +196,11 @@ pub trait BinOp: AnalyzerBackend + Sized { || rhs_cvar.is_symbolic(self).into_expr_err(loc)?, is_return: false, tmp_of: Some(TmpConstruction::new(lhs_cvar, op, Some(rhs_cvar))), + dep_on: { + let mut deps = lhs_cvar.dependent_on(self, true).into_expr_err(loc)?; + deps.extend(rhs_cvar.dependent_on(self, true).into_expr_err(loc)?); + Some(deps) + }, ty: lhs_cvar.underlying(self).into_expr_err(loc)?.ty.clone(), }; @@ -575,6 +588,11 @@ pub trait BinOp: AnalyzerBackend + Sized { RangeOp::Gte, Some(zero_node.into()), )), + dep_on: { + let mut deps = tmp_rhs.dependent_on(self, true).into_expr_err(loc)?; + deps.push(zero_node.into()); + Some(deps) + }, is_symbolic: true, is_return: false, ty: VarType::BuiltIn( @@ -703,6 +721,7 @@ pub trait BinOp: AnalyzerBackend + Sized { storage: None, is_tmp: true, tmp_of: Some(TmpConstruction::new(lhs_cvar, RangeOp::BitNot, None)), + dep_on: Some(lhs_cvar.dependent_on(self, true).into_expr_err(loc)?), is_symbolic: lhs_cvar.is_symbolic(self).into_expr_err(loc)?, is_return: false, ty: lhs_cvar.underlying(self).into_expr_err(loc)?.ty.clone(), diff --git a/crates/solc-expressions/src/cmp.rs b/crates/solc-expressions/src/cmp.rs index 9fd53e3b..b938617d 100644 --- a/crates/solc-expressions/src/cmp.rs +++ b/crates/solc-expressions/src/cmp.rs @@ -65,6 +65,7 @@ pub trait Cmp: AnalyzerBackend + Sized { storage: None, is_tmp: true, tmp_of: Some(TmpConstruction::new(lhs_cvar, RangeOp::Not, None)), + dep_on: Some(lhs_cvar.dependent_on(self, true).into_expr_err(loc)?), is_symbolic: lhs_cvar.is_symbolic(self).into_expr_err(loc)?, is_return: false, ty: VarType::BuiltIn( @@ -221,6 +222,11 @@ pub trait Cmp: AnalyzerBackend + Sized { .into_expr_err(loc)?, is_return: false, tmp_of: Some(TmpConstruction::new(lhs_cvar, op, Some(rhs_cvar))), + dep_on: { + let mut deps = lhs_cvar.dependent_on(self, true).into_expr_err(loc)?; + deps.extend(rhs_cvar.dependent_on(self, true).into_expr_err(loc)?); + Some(deps) + }, ty: VarType::BuiltIn( BuiltInNode::from(self.builtin_or_add(Builtin::Bool)), Some(range), diff --git a/crates/solc-expressions/src/func_call/intrinsic_call/constructors.rs b/crates/solc-expressions/src/func_call/intrinsic_call/constructors.rs index 9a01ba20..bcb5b329 100644 --- a/crates/solc-expressions/src/func_call/intrinsic_call/constructors.rs +++ b/crates/solc-expressions/src/func_call/intrinsic_call/constructors.rs @@ -54,6 +54,7 @@ pub trait ConstructorCaller: is_symbolic: false, is_return: false, tmp_of: None, + dep_on: None, ty: ty.expect("No type for node"), }; @@ -66,6 +67,7 @@ pub trait ConstructorCaller: storage: None, is_tmp: true, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: ContextVarNode::from(len_cvar) diff --git a/crates/solc-expressions/src/func_call/join.rs b/crates/solc-expressions/src/func_call/join.rs index 03fe0b05..adb03fcc 100644 --- a/crates/solc-expressions/src/func_call/join.rs +++ b/crates/solc-expressions/src/func_call/join.rs @@ -1,3 +1,4 @@ +use graph::AsDotStr; use graph::SolcRange; use shared::AnalyzerLike; use graph::nodes::Concrete; @@ -28,6 +29,7 @@ impl FuncJoiner for T where pub trait FuncJoiner: GraphBackend + AnalyzerBackend + Sized + JoinStatTracker { + #[tracing::instrument(level = "trace", skip_all)] fn join( &mut self, ctx: ContextNode, @@ -36,6 +38,7 @@ pub trait FuncJoiner: params: &[FunctionParamNode], func_inputs: &[ContextVarNode], ) -> Result { + 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 @@ -55,6 +58,7 @@ 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)?; let mut rets: Vec<_> = edges[0] .return_nodes(self) @@ -69,7 +73,7 @@ pub trait FuncJoiner: 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.clone(), self); + range.replace_dep(*replace, replacement.0.clone(), self); }); range.cache_eval(self).unwrap(); @@ -77,6 +81,12 @@ pub trait FuncJoiner: new_var.ty.set_range(range).unwrap(); } + 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 } + }); + } + let new_cvar = ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); @@ -91,13 +101,19 @@ pub trait FuncJoiner: 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.clone(), self); + range.replace_dep(*replace, replacement.0.clone(), self); }); range.cache_eval(self).unwrap(); new_var.ty.set_range(range).unwrap(); } + + 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 } + }); + } let new_field = ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); self.add_edge(new_field, new_cvar, Edge::Context(ContextEdge::AttrAccess("field"))); @@ -119,13 +135,18 @@ pub trait FuncJoiner: 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.clone(), self); + range.replace_dep(*replace, replacement.0.clone(), self); }); range.cache_eval(self)?; new_var.ty.set_range(range)?; } + 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 } + }); + } let new_cvar = ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); self.add_edge(new_cvar, ctx, Edge::Context(ContextEdge::Variable)); @@ -158,9 +179,11 @@ 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)?); 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)?; // 1. Create a new variable with name `.` // 2. Set the range to be the copy of the return's simplified range from the function @@ -178,7 +201,7 @@ pub trait FuncJoiner: 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.clone(), self); + range.replace_dep(*replace, replacement.0.clone(), self); }); range.cache_eval(self).unwrap(); @@ -186,6 +209,12 @@ pub trait FuncJoiner: new_var.ty.set_range(range).unwrap(); } + 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 } + }); + } + let new_cvar = ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); self.add_edge(new_cvar, ctx, Edge::Context(ContextEdge::Variable)); @@ -202,13 +231,19 @@ pub trait FuncJoiner: 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.clone(), self); + range.replace_dep(*replace, replacement.0.clone(), self); }); range.cache_eval(self).unwrap(); new_var.ty.set_range(range).unwrap(); } + + 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 } + }); + } let new_field = ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); self.add_edge(new_field, new_cvar, Edge::Context(ContextEdge::AttrAccess("field"))); @@ -230,7 +265,7 @@ pub trait FuncJoiner: 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.clone(), self); + range.replace_dep(*replace, replacement.0.clone(), self); }); range.cache_eval(self)?; @@ -240,6 +275,13 @@ 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 } + }); + } + let new_cvar = ContextVarNode::from(self.add_node(Node::ContextVar(new_var))); @@ -285,11 +327,14 @@ 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)?); self.add_completed_view(false, false, false, body_ctx); } else { + 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)?); self.add_completed_view(false, true, false, body_ctx); } } @@ -302,11 +347,14 @@ pub trait FuncJoiner: { let edges = body_ctx.successful_edges(self).into_expr_err(loc)?; if edges.len() == 1 { + 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)?); self.add_completed_mut(false, false, true, body_ctx); } } else { + tracing::trace!("Childless mut join function: {}", func.name(self).into_expr_err(loc)?); self.add_completed_mut(false, true, false, body_ctx); } } @@ -320,9 +368,9 @@ pub trait FuncJoiner: loc: Loc, params: &[FunctionParamNode], func_inputs: &[ContextVarNode], - ) -> Result>, ExprErr> { + ) -> Result, ContextVarNode)>, ExprErr> { let inputs = ctx.input_variables(self); - let mut replacement_map = BTreeMap::default(); + let mut replacement_map: BTreeMap, ContextVarNode)> = BTreeMap::default(); params .iter() .zip(func_inputs.iter()) @@ -426,9 +474,9 @@ pub trait FuncJoiner: 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_map.insert(next.0.into(), (replacement_field_as_elem.clone(), *replacement_field)); } - replacement_map.insert(field.0.into(), replacement_field_as_elem); + replacement_map.insert(field.0.into(), (replacement_field_as_elem, *replacement_field)); } }); } @@ -438,9 +486,9 @@ 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_map.insert(next.0.into(), (replacement_as_elem.clone(), replacement)); } - replacement_map.insert(correct_input.0.into(), replacement_as_elem); + replacement_map.insert(correct_input.0.into(), (replacement_as_elem, replacement)); } Ok(()) })?; diff --git a/crates/solc-expressions/src/list.rs b/crates/solc-expressions/src/list.rs index 332f451f..0544bd07 100644 --- a/crates/solc-expressions/src/list.rs +++ b/crates/solc-expressions/src/list.rs @@ -68,6 +68,7 @@ pub trait List: AnalyzerBackend + Sized { is_tmp: false, is_symbolic: false, tmp_of: None, + dep_on: None, is_return: false, ty, }; @@ -93,6 +94,7 @@ pub trait List: AnalyzerBackend + Sized { is_tmp: true, is_symbolic: false, tmp_of: None, + dep_on: None, is_return: false, ty, }; diff --git a/crates/solc-expressions/src/member_access/list_access.rs b/crates/solc-expressions/src/member_access/list_access.rs index d5d62ac8..adbbbb8a 100644 --- a/crates/solc-expressions/src/member_access/list_access.rs +++ b/crates/solc-expressions/src/member_access/list_access.rs @@ -167,6 +167,7 @@ pub trait ListAccess: AnalyzerBackend + Si storage: None, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: VarType::BuiltIn( @@ -233,6 +234,7 @@ pub trait ListAccess: AnalyzerBackend + Si storage: None, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: VarType::BuiltIn( diff --git a/crates/solc-expressions/src/require.rs b/crates/solc-expressions/src/require.rs index 08b4a528..bd1ad4a1 100644 --- a/crates/solc-expressions/src/require.rs +++ b/crates/solc-expressions/src/require.rs @@ -519,6 +519,11 @@ pub trait Require: AnalyzerBackend + Variable + BinOp + Sized { RangeOp::Or, 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)?); + Some(deps) + }, ty: VarType::BuiltIn( analyzer.builtin_or_add(Builtin::Bool).into(), Some(range), @@ -802,6 +807,11 @@ pub trait Require: AnalyzerBackend + Variable + BinOp + Sized { storage: None, is_tmp: true, tmp_of: Some(TmpConstruction::new(new_lhs, op, Some(new_rhs))), + dep_on: { + let mut deps = new_lhs.dependent_on(self, true).into_expr_err(loc)?; + deps.extend(new_rhs.dependent_on(self, true).into_expr_err(loc)?); + Some(deps) + }, is_symbolic: new_lhs.is_symbolic(self).into_expr_err(loc)? || new_rhs.is_symbolic(self).into_expr_err(loc)?, is_return: false, @@ -845,6 +855,11 @@ pub trait Require: AnalyzerBackend + Variable + BinOp + Sized { RangeOp::Eq, Some(conditional_cvar), )), + 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)?); + Some(deps) + }, is_symbolic: new_lhs.is_symbolic(self).into_expr_err(loc)? || new_rhs.is_symbolic(self).into_expr_err(loc)?, is_return: false, diff --git a/crates/solc-expressions/src/variable.rs b/crates/solc-expressions/src/variable.rs index 308255d7..1dcd2f75 100644 --- a/crates/solc-expressions/src/variable.rs +++ b/crates/solc-expressions/src/variable.rs @@ -172,6 +172,7 @@ pub trait Variable: AnalyzerBackend + Size is_tmp: false, is_symbolic: true, tmp_of: None, + dep_on: None, is_return: false, ty, }; @@ -199,6 +200,7 @@ pub trait Variable: AnalyzerBackend + Size is_tmp: false, is_symbolic: true, tmp_of: None, + dep_on: None, is_return: false, ty, }; diff --git a/crates/solc-expressions/src/yul/yul_builder.rs b/crates/solc-expressions/src/yul/yul_builder.rs index 1a169940..2fdf9185 100644 --- a/crates/solc-expressions/src/yul/yul_builder.rs +++ b/crates/solc-expressions/src/yul/yul_builder.rs @@ -114,6 +114,7 @@ pub trait YulBuilder: storage: None, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: VarType::try_from_idx(analyzer, b_ty).unwrap(), @@ -421,6 +422,7 @@ pub trait YulBuilder: storage: None, is_tmp: false, tmp_of: None, + dep_on: None, is_symbolic: true, is_return: false, ty: VarType::BuiltIn(