aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/CMakeLists.txt29
-rw-r--r--libsolidity/formal/CVC4Interface.cpp14
-rw-r--r--libsolidity/formal/CVC4Interface.h6
-rw-r--r--libsolidity/formal/SMTChecker.cpp32
-rw-r--r--libsolidity/formal/SMTLib2Interface.cpp13
-rw-r--r--libsolidity/formal/SMTLib2Interface.h6
-rw-r--r--libsolidity/formal/SMTPortfolio.cpp152
-rw-r--r--libsolidity/formal/SMTPortfolio.h67
-rw-r--r--libsolidity/formal/SolverInterface.h19
-rw-r--r--libsolidity/formal/Z3Interface.cpp14
-rw-r--r--libsolidity/formal/Z3Interface.h6
-rw-r--r--libsolidity/interface/StandardCompiler.cpp4
12 files changed, 294 insertions, 68 deletions
diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt
index 0bdec4b4..706b3b08 100644
--- a/libsolidity/CMakeLists.txt
+++ b/libsolidity/CMakeLists.txt
@@ -7,24 +7,27 @@ if (${Z3_FOUND})
include_directories(${Z3_INCLUDE_DIR})
add_definitions(-DHAVE_Z3)
message("Z3 SMT solver found. This enables optional SMT checking with Z3.")
- list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/CVC4Interface.cpp")
else()
list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/Z3Interface.cpp")
- find_package(GMP QUIET)
- find_package(CVC4 QUIET)
- if (${CVC4_FOUND})
- if (${GMP_FOUND})
- include_directories(${CVC4_INCLUDE_DIR})
- add_definitions(-DHAVE_CVC4)
- message("CVC4 SMT solver and GMP found. This enables optional SMT checking with CVC4.")
- else()
- message("CVC4 SMT solver found but its dependency GMP was NOT found. Optional SMT checking with CVC4 will not be available. Please install GMP if it is desired.")
- list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/CVC4Interface.cpp")
- endif()
+endif()
+
+find_package(GMP QUIET)
+find_package(CVC4 QUIET)
+if (${CVC4_FOUND})
+ if (${GMP_FOUND})
+ include_directories(${CVC4_INCLUDE_DIR})
+ add_definitions(-DHAVE_CVC4)
+ message("CVC4 SMT solver and GMP found. This enables optional SMT checking with CVC4.")
else()
- message("No SMT solver found (Z3 or CVC4). Optional SMT checking will not be available. Please install Z3 or CVC4 if it is desired.")
+ message("CVC4 SMT solver found but its dependency GMP was NOT found. Optional SMT checking with CVC4 will not be available. Please install GMP if it is desired.")
list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/CVC4Interface.cpp")
endif()
+else()
+ list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/formal/CVC4Interface.cpp")
+endif()
+
+if (NOT (${Z3_FOUND} OR ${CVC4_FOUND}))
+ message("No SMT solver found. Optional SMT checking will not be available. Please install Z3 or CVC4 if it is desired.")
endif()
add_library(solidity ${sources} ${headers})
diff --git a/libsolidity/formal/CVC4Interface.cpp b/libsolidity/formal/CVC4Interface.cpp
index dba5823a..84d36de0 100644
--- a/libsolidity/formal/CVC4Interface.cpp
+++ b/libsolidity/formal/CVC4Interface.cpp
@@ -37,6 +37,7 @@ void CVC4Interface::reset()
m_functions.clear();
m_solver.reset();
m_solver.setOption("produce-models", true);
+ m_solver.setTimeLimit(queryTimeout);
}
void CVC4Interface::push()
@@ -49,23 +50,20 @@ void CVC4Interface::pop()
m_solver.pop();
}
-Expression CVC4Interface::newFunction(string _name, Sort _domain, Sort _codomain)
+void CVC4Interface::declareFunction(string _name, Sort _domain, Sort _codomain)
{
CVC4::Type fType = m_context.mkFunctionType(cvc4Sort(_domain), cvc4Sort(_codomain));
m_functions.insert({_name, m_context.mkVar(_name.c_str(), fType)});
- return SolverInterface::newFunction(move(_name), _domain, _codomain);
}
-Expression CVC4Interface::newInteger(string _name)
+void CVC4Interface::declareInteger(string _name)
{
m_constants.insert({_name, m_context.mkVar(_name.c_str(), m_context.integerType())});
- return SolverInterface::newInteger(move(_name));
}
-Expression CVC4Interface::newBool(string _name)
+void CVC4Interface::declareBool(string _name)
{
m_constants.insert({_name, m_context.mkVar(_name.c_str(), m_context.booleanType())});
- return SolverInterface::newBool(std::move(_name));
}
void CVC4Interface::addAssertion(Expression const& _expr)
@@ -109,13 +107,13 @@ pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const&
solAssert(false, "");
}
- if (result != CheckResult::UNSATISFIABLE && !_expressionsToEvaluate.empty())
+ if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty())
{
for (Expression const& e: _expressionsToEvaluate)
values.push_back(toString(m_solver.getValue(toCVC4Expr(e))));
}
}
- catch (CVC4::Exception & e)
+ catch (CVC4::Exception const&)
{
result = CheckResult::ERROR;
values.clear();
diff --git a/libsolidity/formal/CVC4Interface.h b/libsolidity/formal/CVC4Interface.h
index cfaeb412..dcd87525 100644
--- a/libsolidity/formal/CVC4Interface.h
+++ b/libsolidity/formal/CVC4Interface.h
@@ -40,9 +40,9 @@ public:
void push() override;
void pop() override;
- Expression newFunction(std::string _name, Sort _domain, Sort _codomain) override;
- Expression newInteger(std::string _name) override;
- Expression newBool(std::string _name) override;
+ void declareFunction(std::string _name, Sort _domain, Sort _codomain) override;
+ void declareInteger(std::string _name) override;
+ void declareBool(std::string _name) override;
void addAssertion(Expression const& _expr) override;
std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
diff --git a/libsolidity/formal/SMTChecker.cpp b/libsolidity/formal/SMTChecker.cpp
index e2a51267..109c8dbe 100644
--- a/libsolidity/formal/SMTChecker.cpp
+++ b/libsolidity/formal/SMTChecker.cpp
@@ -17,13 +17,7 @@
#include <libsolidity/formal/SMTChecker.h>
-#ifdef HAVE_Z3
-#include <libsolidity/formal/Z3Interface.h>
-#elif HAVE_CVC4
-#include <libsolidity/formal/CVC4Interface.h>
-#else
-#include <libsolidity/formal/SMTLib2Interface.h>
-#endif
+#include <libsolidity/formal/SMTPortfolio.h>
#include <libsolidity/formal/SSAVariable.h>
#include <libsolidity/formal/SymbolicIntVariable.h>
@@ -39,16 +33,9 @@ using namespace dev;
using namespace dev::solidity;
SMTChecker::SMTChecker(ErrorReporter& _errorReporter, ReadCallback::Callback const& _readFileCallback):
-#ifdef HAVE_Z3
- m_interface(make_shared<smt::Z3Interface>()),
-#elif HAVE_CVC4
- m_interface(make_shared<smt::CVC4Interface>()),
-#else
- m_interface(make_shared<smt::SMTLib2Interface>(_readFileCallback)),
-#endif
+ m_interface(make_shared<smt::SMTPortfolio>(_readFileCallback)),
m_errorReporter(_errorReporter)
{
- (void)_readFileCallback;
}
void SMTChecker::analyze(SourceUnit const& _source)
@@ -429,7 +416,14 @@ void SMTChecker::arithmeticOperation(BinaryOperation const& _op)
case Token::Div:
{
solAssert(_op.annotation().commonType, "");
- solAssert(_op.annotation().commonType->category() == Type::Category::Integer, "");
+ if (_op.annotation().commonType->category() != Type::Category::Integer)
+ {
+ m_errorReporter.warning(
+ _op.location(),
+ "Assertion checker does not yet implement this operator on non-integer types."
+ );
+ break;
+ }
auto const& intType = dynamic_cast<IntegerType const&>(*_op.annotation().commonType);
smt::Expression left(expr(_op.leftExpression()));
smt::Expression right(expr(_op.rightExpression()));
@@ -623,6 +617,9 @@ void SMTChecker::checkCondition(
case smt::CheckResult::UNKNOWN:
m_errorReporter.warning(_location, _description + " might happen here." + loopComment);
break;
+ case smt::CheckResult::CONFLICTING:
+ m_errorReporter.warning(_location, "At least two SMT solvers provided conflicting answers. Results might not be sound.");
+ break;
case smt::CheckResult::ERROR:
m_errorReporter.warning(_location, "Error trying to invoke SMT solver.");
break;
@@ -650,6 +647,8 @@ void SMTChecker::checkBooleanNotConstant(Expression const& _condition, string co
if (positiveResult == smt::CheckResult::ERROR || negatedResult == smt::CheckResult::ERROR)
m_errorReporter.warning(_condition.location(), "Error trying to invoke SMT solver.");
+ else if (positiveResult == smt::CheckResult::CONFLICTING || negatedResult == smt::CheckResult::CONFLICTING)
+ m_errorReporter.warning(_condition.location(), "At least two SMT solvers provided conflicting answers. Results might not be sound.");
else if (positiveResult == smt::CheckResult::SATISFIABLE && negatedResult == smt::CheckResult::SATISFIABLE)
{
// everything fine.
@@ -752,6 +751,7 @@ void SMTChecker::mergeVariables(vector<VariableDeclaration const*> const& _varia
set<VariableDeclaration const*> uniqueVars(_variables.begin(), _variables.end());
for (auto const* decl: uniqueVars)
{
+ solAssert(_countersEndTrue.count(decl) && _countersEndFalse.count(decl), "");
int trueCounter = _countersEndTrue.at(decl).index();
int falseCounter = _countersEndFalse.at(decl).index();
solAssert(trueCounter != falseCounter, "");
diff --git a/libsolidity/formal/SMTLib2Interface.cpp b/libsolidity/formal/SMTLib2Interface.cpp
index 0e00665a..8cac3cc6 100644
--- a/libsolidity/formal/SMTLib2Interface.cpp
+++ b/libsolidity/formal/SMTLib2Interface.cpp
@@ -62,7 +62,7 @@ void SMTLib2Interface::pop()
m_accumulatedOutput.pop_back();
}
-Expression SMTLib2Interface::newFunction(string _name, Sort _domain, Sort _codomain)
+void SMTLib2Interface::declareFunction(string _name, Sort _domain, Sort _codomain)
{
write(
"(declare-fun |" +
@@ -73,19 +73,16 @@ Expression SMTLib2Interface::newFunction(string _name, Sort _domain, Sort _codom
(_codomain == Sort::Int ? "Int" : "Bool") +
")"
);
- return SolverInterface::newFunction(move(_name), _domain, _codomain);
}
-Expression SMTLib2Interface::newInteger(string _name)
+void SMTLib2Interface::declareInteger(string _name)
{
write("(declare-const |" + _name + "| Int)");
- return SolverInterface::newInteger(move(_name));
}
-Expression SMTLib2Interface::newBool(string _name)
+void SMTLib2Interface::declareBool(string _name)
{
write("(declare-const |" + _name + "| Bool)");
- return SolverInterface::newBool(std::move(_name));
}
void SMTLib2Interface::addAssertion(Expression const& _expr)
@@ -112,7 +109,7 @@ pair<CheckResult, vector<string>> SMTLib2Interface::check(vector<Expression> con
result = CheckResult::ERROR;
vector<string> values;
- if (result != CheckResult::UNSATISFIABLE && result != CheckResult::ERROR)
+ if (result == CheckResult::SATISFIABLE && result != CheckResult::ERROR)
values = parseValues(find(response.cbegin(), response.cend(), '\n'), response.cend());
return make_pair(result, values);
}
@@ -146,7 +143,7 @@ string SMTLib2Interface::checkSatAndGetValuesCommand(vector<Expression> const& _
{
auto const& e = _expressionsToEvaluate.at(i);
solAssert(e.sort == Sort::Int || e.sort == Sort::Bool, "Invalid sort for expression to evaluate.");
- command += "(declare-const |EVALEXPR_" + to_string(i) + "| " + (e.sort == Sort::Int ? "Int" : "Bool") + "\n";
+ command += "(declare-const |EVALEXPR_" + to_string(i) + "| " + (e.sort == Sort::Int ? "Int" : "Bool") + ")\n";
command += "(assert (= |EVALEXPR_" + to_string(i) + "| " + toSExpr(e) + "))\n";
}
command += "(check-sat)\n";
diff --git a/libsolidity/formal/SMTLib2Interface.h b/libsolidity/formal/SMTLib2Interface.h
index 63188acd..61071fe5 100644
--- a/libsolidity/formal/SMTLib2Interface.h
+++ b/libsolidity/formal/SMTLib2Interface.h
@@ -48,9 +48,9 @@ public:
void push() override;
void pop() override;
- Expression newFunction(std::string _name, Sort _domain, Sort _codomain) override;
- Expression newInteger(std::string _name) override;
- Expression newBool(std::string _name) override;
+ void declareFunction(std::string _name, Sort _domain, Sort _codomain) override;
+ void declareInteger(std::string _name) override;
+ void declareBool(std::string _name) override;
void addAssertion(Expression const& _expr) override;
std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
diff --git a/libsolidity/formal/SMTPortfolio.cpp b/libsolidity/formal/SMTPortfolio.cpp
new file mode 100644
index 00000000..8b9fe9ce
--- /dev/null
+++ b/libsolidity/formal/SMTPortfolio.cpp
@@ -0,0 +1,152 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libsolidity/formal/SMTPortfolio.h>
+
+#ifdef HAVE_Z3
+#include <libsolidity/formal/Z3Interface.h>
+#endif
+#ifdef HAVE_CVC4
+#include <libsolidity/formal/CVC4Interface.h>
+#endif
+#if !defined (HAVE_Z3) && !defined (HAVE_CVC4)
+#include <libsolidity/formal/SMTLib2Interface.h>
+#endif
+
+using namespace std;
+using namespace dev;
+using namespace dev::solidity;
+using namespace dev::solidity::smt;
+
+SMTPortfolio::SMTPortfolio(ReadCallback::Callback const& _readCallback)
+{
+#ifdef HAVE_Z3
+ m_solvers.emplace_back(make_shared<smt::Z3Interface>());
+#endif
+#ifdef HAVE_CVC4
+ m_solvers.emplace_back(make_shared<smt::CVC4Interface>());
+#endif
+#if !defined (HAVE_Z3) && !defined (HAVE_CVC4)
+ m_solvers.emplace_back(make_shared<smt::SMTLib2Interface>(_readCallback)),
+#endif
+ (void)_readCallback;
+}
+
+void SMTPortfolio::reset()
+{
+ for (auto s : m_solvers)
+ s->reset();
+}
+
+void SMTPortfolio::push()
+{
+ for (auto s : m_solvers)
+ s->push();
+}
+
+void SMTPortfolio::pop()
+{
+ for (auto s : m_solvers)
+ s->pop();
+}
+
+void SMTPortfolio::declareFunction(string _name, Sort _domain, Sort _codomain)
+{
+ for (auto s : m_solvers)
+ s->declareFunction(_name, _domain, _codomain);
+}
+
+void SMTPortfolio::declareInteger(string _name)
+{
+ for (auto s : m_solvers)
+ s->declareInteger(_name);
+}
+
+void SMTPortfolio::declareBool(string _name)
+{
+ for (auto s : m_solvers)
+ s->declareBool(_name);
+}
+
+void SMTPortfolio::addAssertion(Expression const& _expr)
+{
+ for (auto s : m_solvers)
+ s->addAssertion(_expr);
+}
+
+/*
+ * Broadcasts the SMT query to all solvers and returns a single result.
+ * This comment explains how this result is decided.
+ *
+ * When a solver is queried, there are four possible answers:
+ * SATISFIABLE (SAT), UNSATISFIABLE (UNSAT), UNKNOWN, CONFLICTING, ERROR
+ * We say that a solver _answered_ the query if it returns either:
+ * SAT or UNSAT
+ * A solver did not answer the query if it returns either:
+ * UNKNOWN (it tried but couldn't solve it) or ERROR (crash, internal error, API error, etc).
+ *
+ * Ideally all solvers answer the query and agree on what the answer is
+ * (all say SAT or all say UNSAT).
+ *
+ * The actual logic as as follows:
+ * 1) If at least one solver answers the query, all the non-answer results are ignored.
+ * Here SAT/UNSAT is preferred over UNKNOWN since it's an actual answer, and over ERROR
+ * because one buggy solver/integration shouldn't break the portfolio.
+ *
+ * 2) If at least one solver answers SAT and at least one answers UNSAT, at least one of them is buggy
+ * and the result is CONFLICTING.
+ * In the future if we have more than 2 solvers enabled we could go with the majority.
+ *
+ * 3) If NO solver answers the query:
+ * If at least one solver returned UNKNOWN (where the rest returned ERROR), the result is UNKNOWN.
+ * This is preferred over ERROR since the SMTChecker might decide to abstract the query
+ * when it is told that this is a hard query to solve.
+ *
+ * If all solvers return ERROR, the result is ERROR.
+*/
+pair<CheckResult, vector<string>> SMTPortfolio::check(vector<Expression> const& _expressionsToEvaluate)
+{
+ CheckResult lastResult = CheckResult::ERROR;
+ vector<string> finalValues;
+ for (auto s : m_solvers)
+ {
+ CheckResult result;
+ vector<string> values;
+ tie(result, values) = s->check(_expressionsToEvaluate);
+ if (solverAnswered(result))
+ {
+ if (!solverAnswered(lastResult))
+ {
+ lastResult = result;
+ finalValues = std::move(values);
+ }
+ else if (lastResult != result)
+ {
+ lastResult = CheckResult::CONFLICTING;
+ break;
+ }
+ }
+ else if (result == CheckResult::UNKNOWN && lastResult == CheckResult::ERROR)
+ lastResult = result;
+ }
+ return make_pair(lastResult, finalValues);
+}
+
+bool SMTPortfolio::solverAnswered(CheckResult result)
+{
+ return result == CheckResult::SATISFIABLE || result == CheckResult::UNSATISFIABLE;
+}
diff --git a/libsolidity/formal/SMTPortfolio.h b/libsolidity/formal/SMTPortfolio.h
new file mode 100644
index 00000000..96c7ff57
--- /dev/null
+++ b/libsolidity/formal/SMTPortfolio.h
@@ -0,0 +1,67 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+
+#include <libsolidity/formal/SolverInterface.h>
+
+#include <libsolidity/interface/ReadFile.h>
+
+#include <boost/noncopyable.hpp>
+
+#include <vector>
+
+namespace dev
+{
+namespace solidity
+{
+namespace smt
+{
+
+/**
+ * The SMTPortfolio wraps all available solvers within a single interface,
+ * propagating the functionalities to all solvers.
+ * It also checks whether different solvers give conflicting answers
+ * to SMT queries.
+ */
+class SMTPortfolio: public SolverInterface, public boost::noncopyable
+{
+public:
+ SMTPortfolio(ReadCallback::Callback const& _readCallback);
+
+ void reset() override;
+
+ void push() override;
+ void pop() override;
+
+ void declareFunction(std::string _name, Sort _domain, Sort _codomain) override;
+ void declareInteger(std::string _name) override;
+ void declareBool(std::string _name) override;
+
+ void addAssertion(Expression const& _expr) override;
+ std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
+
+private:
+ static bool solverAnswered(CheckResult result);
+
+ std::vector<std::shared_ptr<smt::SolverInterface>> m_solvers;
+};
+
+}
+}
+}
diff --git a/libsolidity/formal/SolverInterface.h b/libsolidity/formal/SolverInterface.h
index 16796684..8bbd0417 100644
--- a/libsolidity/formal/SolverInterface.h
+++ b/libsolidity/formal/SolverInterface.h
@@ -39,7 +39,7 @@ namespace smt
enum class CheckResult
{
- SATISFIABLE, UNSATISFIABLE, UNKNOWN, ERROR
+ SATISFIABLE, UNSATISFIABLE, UNKNOWN, CONFLICTING, ERROR
};
enum class Sort
@@ -199,8 +199,10 @@ public:
virtual void push() = 0;
virtual void pop() = 0;
- virtual Expression newFunction(std::string _name, Sort _domain, Sort _codomain)
+ virtual void declareFunction(std::string _name, Sort _domain, Sort _codomain) = 0;
+ Expression newFunction(std::string _name, Sort _domain, Sort _codomain)
{
+ declareFunction(_name, _domain, _codomain);
solAssert(_domain == Sort::Int, "Function sort not supported.");
// Subclasses should do something here
switch (_codomain)
@@ -214,14 +216,18 @@ public:
break;
}
}
- virtual Expression newInteger(std::string _name)
+ virtual void declareInteger(std::string _name) = 0;
+ Expression newInteger(std::string _name)
{
// Subclasses should do something here
+ declareInteger(_name);
return Expression(std::move(_name), {}, Sort::Int);
}
- virtual Expression newBool(std::string _name)
+ virtual void declareBool(std::string _name) = 0;
+ Expression newBool(std::string _name)
{
// Subclasses should do something here
+ declareBool(_name);
return Expression(std::move(_name), {}, Sort::Bool);
}
@@ -231,8 +237,11 @@ public:
/// is available. Throws SMTSolverError on error.
virtual std::pair<CheckResult, std::vector<std::string>>
check(std::vector<Expression> const& _expressionsToEvaluate) = 0;
-};
+protected:
+ // SMT query timeout in milliseconds.
+ static int const queryTimeout = 10000;
+};
}
}
diff --git a/libsolidity/formal/Z3Interface.cpp b/libsolidity/formal/Z3Interface.cpp
index 41943c92..784fbd28 100644
--- a/libsolidity/formal/Z3Interface.cpp
+++ b/libsolidity/formal/Z3Interface.cpp
@@ -28,7 +28,10 @@ using namespace dev::solidity::smt;
Z3Interface::Z3Interface():
m_solver(m_context)
{
+ // This needs to be set globally.
z3::set_param("rewriter.pull_cheap_ite", true);
+ // This needs to be set in the context.
+ m_context.set("timeout", queryTimeout);
}
void Z3Interface::reset()
@@ -48,22 +51,19 @@ void Z3Interface::pop()
m_solver.pop();
}
-Expression Z3Interface::newFunction(string _name, Sort _domain, Sort _codomain)
+void Z3Interface::declareFunction(string _name, Sort _domain, Sort _codomain)
{
m_functions.insert({_name, m_context.function(_name.c_str(), z3Sort(_domain), z3Sort(_codomain))});
- return SolverInterface::newFunction(move(_name), _domain, _codomain);
}
-Expression Z3Interface::newInteger(string _name)
+void Z3Interface::declareInteger(string _name)
{
m_constants.insert({_name, m_context.int_const(_name.c_str())});
- return SolverInterface::newInteger(move(_name));
}
-Expression Z3Interface::newBool(string _name)
+void Z3Interface::declareBool(string _name)
{
m_constants.insert({_name, m_context.bool_const(_name.c_str())});
- return SolverInterface::newBool(std::move(_name));
}
void Z3Interface::addAssertion(Expression const& _expr)
@@ -92,7 +92,7 @@ pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _
solAssert(false, "");
}
- if (result != CheckResult::UNSATISFIABLE && !_expressionsToEvaluate.empty())
+ if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty())
{
z3::model m = m_solver.get_model();
for (Expression const& e: _expressionsToEvaluate)
diff --git a/libsolidity/formal/Z3Interface.h b/libsolidity/formal/Z3Interface.h
index 354ded25..84880ff3 100644
--- a/libsolidity/formal/Z3Interface.h
+++ b/libsolidity/formal/Z3Interface.h
@@ -40,9 +40,9 @@ public:
void push() override;
void pop() override;
- Expression newFunction(std::string _name, Sort _domain, Sort _codomain) override;
- Expression newInteger(std::string _name) override;
- Expression newBool(std::string _name) override;
+ void declareFunction(std::string _name, Sort _domain, Sort _codomain) override;
+ void declareInteger(std::string _name) override;
+ void declareBool(std::string _name) override;
void addAssertion(Expression const& _expr) override;
std::pair<CheckResult, std::vector<std::string>> check(std::vector<Expression> const& _expressionsToEvaluate) override;
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index c8d43e9f..8339780f 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -600,7 +600,7 @@ string StandardCompiler::compile(string const& _input)
if (!jsonParseStrict(_input, input, &errors))
return jsonCompactPrint(formatFatalError("JSONError", errors));
}
- catch(...)
+ catch (...)
{
return "{\"errors\":\"[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error parsing input JSON.\"}]}";
}
@@ -613,7 +613,7 @@ string StandardCompiler::compile(string const& _input)
{
return jsonCompactPrint(output);
}
- catch(...)
+ catch (...)
{
return "{\"errors\":\"[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error writing output JSON.\"}]}";
}