Skip to content

Commit

Permalink
fix ifs, add more support
Browse files Browse the repository at this point in the history
  • Loading branch information
brockelmore committed Jul 17, 2024
1 parent 76d4bb1 commit 53e4c21
Show file tree
Hide file tree
Showing 19 changed files with 872 additions and 705 deletions.
26 changes: 23 additions & 3 deletions crates/graph/src/nodes/context/underlying.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
ModifierState,
},
solvers::dl::DLSolver,
AnalyzerBackend,
AnalyzerBackend, ContextEdge, Edge, Node,
};

use shared::GraphError;
Expand Down Expand Up @@ -340,6 +340,12 @@ pub struct Context {
pub applies: Vec<FunctionNode>,
}

impl From<Context> for Node {
fn from(c: Context) -> Node {
Node::Context(c)
}
}

impl Context {
/// Creates a new context from a function
pub fn new(parent_fn: FunctionNode, fn_name: String, loc: Loc) -> Self {
Expand Down Expand Up @@ -446,13 +452,27 @@ impl Context {
})
}

pub fn add_subctx(
subctx_kind: SubContextKind,
loc: Loc,
analyzer: &mut impl AnalyzerBackend,
modifier_state: Option<ModifierState>,
) -> Result<ContextNode, GraphError> {
let ctx = Context::new_subctx(subctx_kind, loc, analyzer, modifier_state)?;
let ctx_node = ContextNode::from(analyzer.add_node(ctx));
if let Some(cont) = ctx_node.underlying(analyzer)?.continuation_of() {
analyzer.add_edge(ctx_node, cont, Edge::Context(ContextEdge::Continue("TODO")));
}
Ok(ctx_node)
}

pub fn new_loop_subctx(
parent_ctx: ContextNode,
loc: Loc,
analyzer: &mut impl AnalyzerBackend,
) -> Result<Self, GraphError> {
) -> Result<ContextNode, GraphError> {
let subctx_kind = SubContextKind::Loop { parent_ctx };
Context::new_subctx(subctx_kind, loc, analyzer, None)
Context::add_subctx(subctx_kind, loc, analyzer, None)
}

/// Set the child context to a fork
Expand Down
14 changes: 10 additions & 4 deletions crates/graph/src/nodes/context/variables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,16 @@ impl ContextNode {
name: &str,
) -> Result<Option<ContextVarNode>, GraphError> {
if let Some(var) = self.var_by_name(analyzer, name) {
Ok(Some(var))
} else if let Some(parent) = self.ancestor_in_fn(analyzer, self.associated_fn(analyzer)?)? {
parent.var_by_name_or_recurse(analyzer, name)
} else if let Some(parent) = self.underlying(analyzer)?.continuation_of() {
return Ok(Some(var));
}

if let Some(parent) = self.ancestor_in_fn(analyzer, self.associated_fn(analyzer)?)? {
if let Some(in_parent) = parent.var_by_name_or_recurse(analyzer, name)? {
return Ok(Some(in_parent));
}
}

if let Some(parent) = self.underlying(analyzer)?.continuation_of() {
parent.var_by_name_or_recurse(analyzer, name)
} else {
Ok(None)
Expand Down
6 changes: 2 additions & 4 deletions crates/graph/src/nodes/context/versioning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ impl ContextNode {
for _ in 0..end_worlds.len().saturating_sub(1) {
let curr = stack.pop_front().unwrap();

let left_ctx = Context::new_subctx(
let left_subctx = Context::add_subctx(
SubContextKind::Fork {
parent_ctx: curr,
true_side: true,
Expand All @@ -331,8 +331,7 @@ impl ContextNode {
analyzer,
None,
)?;
let left_subctx = ContextNode::from(analyzer.add_node(Node::Context(left_ctx)));
let right_ctx = Context::new_subctx(
let right_subctx = Context::add_subctx(
SubContextKind::Fork {
parent_ctx: curr,
true_side: false,
Expand All @@ -341,7 +340,6 @@ impl ContextNode {
analyzer,
None,
)?;
let right_subctx = ContextNode::from(analyzer.add_node(Node::Context(right_ctx)));
curr.set_child_fork(left_subctx, right_subctx, analyzer)?;

stack.push_back(left_subctx);
Expand Down
31 changes: 21 additions & 10 deletions crates/pyrometer/tests/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use analyzers::FunctionVarsBoundAnalyzer;
use analyzers::ReportConfig;
use analyzers::ReportDisplay;
use ariadne::sources;
use graph::nodes::KilledKind;
use graph::{
elem::Elem,
nodes::{Concrete, FunctionNode},
Expand Down Expand Up @@ -91,21 +92,31 @@ pub fn no_ctx_killed(
let funcs = analyzer.search_children(entry, &Edge::Func);
for func in funcs.into_iter() {
if let Some(ctx) = FunctionNode::from(func).maybe_body_ctx(&mut analyzer) {
if ctx.killed_loc(&analyzer).unwrap().is_some() {
analyzer
.bounds_for_all(arena, &file_mapping, ctx, config)
.as_cli_compat(&file_mapping)
.print_reports(&mut source_map, &analyzer, arena);
panic!("Killed context in test");
}
ctx.all_edges(&analyzer).unwrap().iter().for_each(|subctx| {
if subctx.killed_loc(&analyzer).unwrap().is_some() {
let maybe_killed = ctx.killed_loc(&analyzer).unwrap();
match maybe_killed {
Some((_, KilledKind::Ended)) => {}
Some(..) => {
analyzer
.bounds_for_all(arena, &file_mapping, *subctx, config)
.bounds_for_all(arena, &file_mapping, ctx, config)
.as_cli_compat(&file_mapping)
.print_reports(&mut source_map, &analyzer, arena);
panic!("Killed context in test");
}
_ => {}
}
ctx.all_edges(&analyzer).unwrap().iter().for_each(|subctx| {
let maybe_killed = subctx.killed_loc(&analyzer).unwrap();
match maybe_killed {
Some((_, KilledKind::Ended)) => {}
Some(..) => {
analyzer
.bounds_for_all(arena, &file_mapping, ctx, config)
.as_cli_compat(&file_mapping)
.print_reports(&mut source_map, &analyzer, arena);
panic!("Killed context in test");
}
_ => {}
}
});
}
}
Expand Down
58 changes: 29 additions & 29 deletions crates/pyrometer/tests/test_data/abstract.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,32 @@ abstract contract A {
function bar() internal view virtual returns (uint);
}

abstract contract YInterface {
function foo() external virtual returns (uint);
}

contract Y is YInterface {
function foo() public virtual override returns (uint) {
return 1;
}

function bar(Y y) internal {
y.foo();
}
}

abstract contract Base {
function foo() public virtual returns (uint) {
return 0;
}
}

contract Base2 is Base {}

contract Base3 is Base2 {}

contract Test is Base3 {
function foo() public override returns (uint) {
return super.foo();
}
}
// abstract contract YInterface {
// function foo() external virtual returns (uint);
// }

// contract Y is YInterface {
// function foo() public virtual override returns (uint) {
// return 1;
// }

// function bar(Y y) internal {
// y.foo();
// }
// }

// abstract contract Base {
// function foo() public virtual returns (uint) {
// return 0;
// }
// }

// contract Base2 is Base {}

// contract Base3 is Base2 {}

// contract Test is Base3 {
// function foo() public override returns (uint) {
// return super.foo();
// }
// }
4 changes: 2 additions & 2 deletions crates/shared/src/flattened.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use solang_parser::pt::{Expression, Loc, NamedArgument, Type};

#[derive(Debug, Clone, Copy)]
pub enum ExprFlag {
FunctionName(usize, bool),
FunctionName(usize, bool, bool),
New,
Negate,
Requirement,
Expand All @@ -21,7 +21,7 @@ pub enum FlatExpr {
},

NamedArgument(Loc, &'static str),
FunctionCallName(usize, bool),
FunctionCallName(usize, bool, bool),
Requirement(Loc),
Super(Loc, &'static str),

Expand Down
4 changes: 2 additions & 2 deletions crates/solc-expressions/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ pub trait Array: AnalyzerBackend<Expr = Expression, ExprErr = ExprErr> + Sized {
analyzer.index_into_array_inner(
arena,
ctx,
loc,
inner_tys.flatten(),
index_tys.clone().flatten(),
loc,
)
})
})
Expand All @@ -122,9 +122,9 @@ pub trait Array: AnalyzerBackend<Expr = Expression, ExprErr = ExprErr> + Sized {
&mut self,
arena: &mut RangeArena<Elem<Concrete>>,
ctx: ContextNode,
loc: Loc,
inner_paths: ExprRet,
index_paths: ExprRet,
loc: Loc,
) -> Result<(), ExprErr> {
match (inner_paths, index_paths) {
(_, ExprRet::Null) | (ExprRet::Null, _) => Ok(()),
Expand Down
8 changes: 4 additions & 4 deletions crates/solc-expressions/src/cond_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ pub trait CondOp: AnalyzerBackend<Expr = Expression, ExprErr = ExprErr> + Requir
panic!("cond op");
// self.apply_to_edges(ctx, loc, arena, &|analyzer, arena, ctx, loc| {
// let tctx =
// Context::new_subctx(ctx, None, loc, Some("true"), None, false, analyzer, None)
// Context::add_subctx(ctx, None, loc, Some("true"), None, false, analyzer, None)
// .into_expr_err(loc)?;
// let true_subctx = ContextNode::from(analyzer.add_node(Node::Context(tctx)));
// let fctx =
// Context::new_subctx(ctx, None, loc, Some("false"), None, false, analyzer, None)
// Context::add_subctx(ctx, None, loc, Some("false"), None, false, analyzer, None)
// .into_expr_err(loc)?;
// let false_subctx = ContextNode::from(analyzer.add_node(Node::Context(fctx)));
// ctx.set_child_fork(true_subctx, false_subctx, analyzer)
Expand Down Expand Up @@ -176,12 +176,12 @@ pub trait CondOp: AnalyzerBackend<Expr = Expression, ExprErr = ExprErr> + Requir
// self.apply_to_edges(ctx, loc, arena, &|analyzer, arena, ctx, loc| {
// let true_subctx_kind = SubContextKind::new_fork(ctx, true);
// let tctx =
// Context::new_subctx(true_subctx_kind, loc, analyzer, None).into_expr_err(loc)?;
// Context::add_subctx(true_subctx_kind, loc, analyzer, None).into_expr_err(loc)?;
// let true_subctx = ContextNode::from(analyzer.add_node(Node::Context(tctx)));

// let false_subctx_kind = SubContextKind::new_fork(ctx, false);
// let fctx =
// Context::new_subctx(false_subctx_kind, loc, analyzer, None).into_expr_err(loc)?;
// Context::add_subctx(false_subctx_kind, loc, analyzer, None).into_expr_err(loc)?;
// let false_subctx = ContextNode::from(analyzer.add_node(Node::Context(fctx)));
// ctx.set_child_fork(true_subctx, false_subctx, analyzer)
// .into_expr_err(loc)?;
Expand Down
Loading

0 comments on commit 53e4c21

Please sign in to comment.