diff --git a/crates/graph/src/nodes/context/typing.rs b/crates/graph/src/nodes/context/typing.rs index 68d2e25e..0c64b7ee 100644 --- a/crates/graph/src/nodes/context/typing.rs +++ b/crates/graph/src/nodes/context/typing.rs @@ -89,6 +89,7 @@ impl ContextNode { .underlying(analyzer)? .inherits .iter() + .filter_map(|i| i.as_ref()) .any(|inherited| *inherited == fn_ctrt)) } else { Ok(false) diff --git a/crates/graph/src/nodes/contract_ty.rs b/crates/graph/src/nodes/contract_ty.rs index 4e946351..a91138c3 100644 --- a/crates/graph/src/nodes/contract_ty.rs +++ b/crates/graph/src/nodes/contract_ty.rs @@ -108,7 +108,7 @@ impl ContractNode { self.underlying_mut(analyzer) .unwrap() .inherits - .push(ContractNode::from(*found)); + .push(Some(ContractNode::from(*found))); analyzer.add_edge(*found, *self, Edge::InheritedContract); }); self.order_inherits(analyzer); @@ -119,17 +119,25 @@ impl ContractNode { let inherits = self.underlying(analyzer).unwrap().inherits.clone(); let mut tmp_inherits = vec![]; - tmp_inherits.resize(inherits.len(), ContractNode::from(NodeIdx::from(0))); + tmp_inherits.resize(inherits.len(), None); inherits.into_iter().for_each(|inherited| { - let i_name = inherited.name(analyzer).unwrap(); - let position = raw_inherits.iter().position(|raw| &i_name == raw).unwrap(); - tmp_inherits[position] = inherited; + if let Some(inherited) = inherited { + let i_name = inherited.name(analyzer).unwrap(); + let position = raw_inherits.iter().position(|raw| &i_name == raw).unwrap(); + tmp_inherits[position] = Some(inherited); + } }); self.underlying_mut(analyzer).unwrap().inherits = tmp_inherits; } pub fn direct_inherited_contracts(&self, analyzer: &impl GraphBackend) -> Vec { - self.underlying(analyzer).unwrap().inherits.clone() + self.underlying(analyzer) + .unwrap() + .inherits + .iter() + .filter_map(|i| i.as_ref()) + .cloned() + .collect() } pub fn all_inherited_contracts(&self, analyzer: &impl GraphBackend) -> Vec { @@ -384,7 +392,7 @@ pub struct Contract { /// Raw inherited strings, ordered by least base to most base pub raw_inherits: Vec, /// A list of contracts that this contract inherits (TODO: inheritance linearization) - pub inherits: Vec, + pub inherits: Vec>, /// Cached linearized functions pub cached_functions: Option>, } @@ -416,7 +424,7 @@ impl Contract { { let name = ContractNode::from(contract).name(analyzer).unwrap(); if &name == inherited_name { - inherits.push(ContractNode::from(contract)); + inherits.push(Some(ContractNode::from(contract))); found = true; break; } @@ -430,7 +438,7 @@ impl Contract { { let name = ContractNode::from(contract).name(analyzer).unwrap(); if &name == inherited_name { - inherits.push(ContractNode::from(contract)); + inherits.push(Some(ContractNode::from(contract))); found = true; break; } @@ -462,11 +470,13 @@ impl Contract { let inherits = self.inherits.clone(); let mut tmp_inherits = vec![]; - tmp_inherits.resize(inherits.len(), ContractNode::from(NodeIdx::from(0))); + tmp_inherits.resize(raw_inherits.len(), None); inherits.into_iter().for_each(|inherited| { - let i_name = inherited.name(analyzer).unwrap(); - let position = raw_inherits.iter().position(|raw| &i_name == raw).unwrap(); - tmp_inherits[position] = inherited; + if let Some(inherited) = inherited { + let i_name = inherited.name(analyzer).unwrap(); + let position = raw_inherits.iter().position(|raw| &i_name == raw).unwrap(); + tmp_inherits[position] = Some(inherited); + } }); self.inherits = tmp_inherits; } diff --git a/crates/pyrometer/src/analyzer.rs b/crates/pyrometer/src/analyzer.rs index 82665d06..6aeda249 100644 --- a/crates/pyrometer/src/analyzer.rs +++ b/crates/pyrometer/src/analyzer.rs @@ -1049,8 +1049,8 @@ impl Analyzer { node.into() }; - inherits.iter().for_each(|contract_node| { - self.add_edge(*contract_node, con_node, Edge::InheritedContract); + inherits.into_iter().flatten().for_each(|contract_node| { + self.add_edge(contract_node, con_node, Edge::InheritedContract); }); let mut usings = vec![]; diff --git a/crates/shared/src/flattened.rs b/crates/shared/src/flattened.rs index bc753c46..86fa3502 100644 --- a/crates/shared/src/flattened.rs +++ b/crates/shared/src/flattened.rs @@ -38,6 +38,7 @@ pub enum FlatExpr { }, Todo(Loc, &'static str), + Pop, Emit(Loc), TestCommand(Loc, &'static str), @@ -399,6 +400,7 @@ impl FlatExpr { | ArrayLiteral(loc, ..) => Some(*loc), FunctionCallName(..) + | Pop | YulExpr(FlatYulExpr::YulStartBlock(_)) | YulExpr(FlatYulExpr::YulEndBlock(_)) => None, } diff --git a/crates/solc-expressions/src/context_builder/flattened.rs b/crates/solc-expressions/src/context_builder/flattened.rs index f16f645b..4d8722f1 100644 --- a/crates/solc-expressions/src/context_builder/flattened.rs +++ b/crates/solc-expressions/src/context_builder/flattened.rs @@ -842,6 +842,9 @@ pub trait Flatten: }); let cmp = self.expr_stack_mut().pop().unwrap(); self.traverse_requirement(cmp, *loc); + if input_exprs.len() > 1 { + self.push_expr(FlatExpr::Pop); + } } _ => { // func(inputs) @@ -1146,6 +1149,12 @@ pub trait Flatten: // Semi useless Super(..) => unreachable!(), Parameter(_, _, _) => Ok(()), + Pop => { + let _ = ctx + .pop_n_latest_exprs(1, Loc::Implicit, self) + .into_expr_err(Loc::Implicit)?; + Ok(()) + } Emit(loc) => { let _ = ctx.pop_n_latest_exprs(1, loc, self).into_expr_err(loc)?; Ok(())