aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/formal/SMTChecker.h
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/formal/SMTChecker.h')
-rw-r--r--libsolidity/formal/SMTChecker.h53
1 files changed, 42 insertions, 11 deletions
diff --git a/libsolidity/formal/SMTChecker.h b/libsolidity/formal/SMTChecker.h
index 8e07d74d..b57f0f96 100644
--- a/libsolidity/formal/SMTChecker.h
+++ b/libsolidity/formal/SMTChecker.h
@@ -26,6 +26,7 @@
#include <map>
#include <string>
+#include <vector>
namespace dev
{
@@ -57,6 +58,7 @@ private:
virtual void endVisit(ExpressionStatement const& _node) override;
virtual void endVisit(Assignment const& _node) override;
virtual void endVisit(TupleExpression const& _node) override;
+ virtual void endVisit(UnaryOperation const& _node) override;
virtual void endVisit(BinaryOperation const& _node) override;
virtual void endVisit(FunctionCall const& _node) override;
virtual void endVisit(Identifier const& _node) override;
@@ -66,12 +68,21 @@ private:
void compareOperation(BinaryOperation const& _op);
void booleanOperation(BinaryOperation const& _op);
- void assignment(Declaration const& _variable, Expression const& _value);
+ /// Division expression in the given type. Requires special treatment because
+ /// of rounding for signed division.
+ smt::Expression division(smt::Expression _left, smt::Expression _right, IntegerType const& _type);
- // Visits the branch given by the statement, pushes and pops the SMT checker.
- // @param _condition if present, asserts that this condition is true within the branch.
- void visitBranch(Statement const& _statement, smt::Expression const* _condition = nullptr);
- void visitBranch(Statement const& _statement, smt::Expression _condition);
+ void assignment(Declaration const& _variable, Expression const& _value, SourceLocation const& _location);
+ void assignment(Declaration const& _variable, smt::Expression const& _value, SourceLocation const& _location);
+
+ /// Maps a variable to an SSA index.
+ using VariableSequenceCounters = std::map<Declaration const*, int>;
+
+ /// Visits the branch given by the statement, pushes and pops the current path conditions.
+ /// @param _condition if present, asserts that this condition is true within the branch.
+ /// @returns the variable sequence counter after visiting the branch.
+ VariableSequenceCounters visitBranch(Statement const& _statement, smt::Expression const* _condition = nullptr);
+ VariableSequenceCounters visitBranch(Statement const& _statement, smt::Expression _condition);
/// Check that a condition can be satisfied.
void checkCondition(
@@ -88,14 +99,21 @@ private:
Expression const& _condition,
std::string const& _description
);
+ /// Checks that the value is in the range given by the type.
+ void checkUnderOverflow(smt::Expression _value, IntegerType const& _Type, SourceLocation const& _location);
+
std::pair<smt::CheckResult, std::vector<std::string>>
- checkSatisifableAndGenerateModel(std::vector<smt::Expression> const& _expressionsToEvaluate);
+ checkSatisfiableAndGenerateModel(std::vector<smt::Expression> const& _expressionsToEvaluate);
- smt::CheckResult checkSatisifable();
+ smt::CheckResult checkSatisfiable();
void initializeLocalVariables(FunctionDefinition const& _function);
void resetVariables(std::vector<Declaration const*> _variables);
+ /// Given two different branches and the touched variables,
+ /// merge the touched variables into after-branch ite variables
+ /// using the branch condition as guard.
+ void mergeVariables(std::vector<Declaration const*> const& _variables, smt::Expression const& _condition, VariableSequenceCounters const& _countersEndTrue, VariableSequenceCounters const& _countersEndFalse);
/// Tries to create an uninitialized variable and returns true on success.
/// This fails if the type is not supported.
bool createVariable(VariableDeclaration const& _varDecl);
@@ -124,15 +142,27 @@ private:
static smt::Expression minValue(IntegerType const& _t);
static smt::Expression maxValue(IntegerType const& _t);
- using VariableSequenceCounters = std::map<Declaration const*, int>;
-
- /// Returns the expression corresponding to the AST node. Creates a new expression
- /// if it does not exist yet.
+ /// Returns the expression corresponding to the AST node. Throws if the expression does not exist.
smt::Expression expr(Expression const& _e);
+ /// Creates the expression (value can be arbitrary)
+ void createExpr(Expression const& _e);
+ /// Creates the expression and sets its value.
+ void defineExpr(Expression const& _e, smt::Expression _value);
/// Returns the function declaration corresponding to the given variable.
/// The function takes one argument which is the "sequence number".
smt::Expression var(Declaration const& _decl);
+ /// Adds a new path condition
+ void pushPathCondition(smt::Expression const& _e);
+ /// Remove the last path condition
+ void popPathCondition();
+ /// Returns the conjunction of all path conditions or True if empty
+ smt::Expression currentPathConditions();
+ /// Conjoin the current path conditions with the given parameter and add to the solver
+ void addPathConjoinedExpression(smt::Expression const& _e);
+ /// Add to the solver: the given expression implied by the current path conditions
+ void addPathImpliedExpression(smt::Expression const& _e);
+
std::shared_ptr<smt::SolverInterface> m_interface;
std::shared_ptr<VariableUsage> m_variableUsage;
bool m_conditionalExecutionHappened = false;
@@ -140,6 +170,7 @@ private:
std::map<Declaration const*, int> m_nextFreeSequenceCounter;
std::map<Expression const*, smt::Expression> m_expressions;
std::map<Declaration const*, smt::Expression> m_variables;
+ std::vector<smt::Expression> m_pathConditions;
ErrorReporter& m_errorReporter;
FunctionDefinition const* m_currentFunction = nullptr;