mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Purge using namespace std in libsmtutil and libsolc
This commit is contained in:
parent
1ac883b84d
commit
62723b7534
@ -31,20 +31,19 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
using namespace solidity::smtutil;
|
using namespace solidity::smtutil;
|
||||||
|
|
||||||
CHCSmtLib2Interface::CHCSmtLib2Interface(
|
CHCSmtLib2Interface::CHCSmtLib2Interface(
|
||||||
map<h256, string> const& _queryResponses,
|
std::map<h256, std::string> const& _queryResponses,
|
||||||
ReadCallback::Callback _smtCallback,
|
ReadCallback::Callback _smtCallback,
|
||||||
SMTSolverChoice _enabledSolvers,
|
SMTSolverChoice _enabledSolvers,
|
||||||
optional<unsigned> _queryTimeout
|
std::optional<unsigned> _queryTimeout
|
||||||
):
|
):
|
||||||
CHCSolverInterface(_queryTimeout),
|
CHCSolverInterface(_queryTimeout),
|
||||||
m_smtlib2(make_unique<SMTLib2Interface>(_queryResponses, _smtCallback, m_queryTimeout)),
|
m_smtlib2(std::make_unique<SMTLib2Interface>(_queryResponses, _smtCallback, m_queryTimeout)),
|
||||||
m_queryResponses(std::move(_queryResponses)),
|
m_queryResponses(std::move(_queryResponses)),
|
||||||
m_smtCallback(_smtCallback),
|
m_smtCallback(_smtCallback),
|
||||||
m_enabledSolvers(_enabledSolvers)
|
m_enabledSolvers(_enabledSolvers)
|
||||||
@ -66,8 +65,8 @@ void CHCSmtLib2Interface::registerRelation(Expression const& _expr)
|
|||||||
smtAssert(_expr.sort->kind == Kind::Function);
|
smtAssert(_expr.sort->kind == Kind::Function);
|
||||||
if (!m_variables.count(_expr.name))
|
if (!m_variables.count(_expr.name))
|
||||||
{
|
{
|
||||||
auto fSort = dynamic_pointer_cast<FunctionSort>(_expr.sort);
|
auto fSort = std::dynamic_pointer_cast<FunctionSort>(_expr.sort);
|
||||||
string domain = toSmtLibSort(fSort->domain);
|
std::string domain = toSmtLibSort(fSort->domain);
|
||||||
// Relations are predicates which have implicit codomain Bool.
|
// Relations are predicates which have implicit codomain Bool.
|
||||||
m_variables.insert(_expr.name);
|
m_variables.insert(_expr.name);
|
||||||
write(
|
write(
|
||||||
@ -89,10 +88,10 @@ void CHCSmtLib2Interface::addRule(Expression const& _expr, std::string const& /*
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> CHCSmtLib2Interface::query(Expression const& _block)
|
std::tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> CHCSmtLib2Interface::query(Expression const& _block)
|
||||||
{
|
{
|
||||||
string query = dumpQuery(_block);
|
std::string query = dumpQuery(_block);
|
||||||
string response = querySolver(query);
|
std::string response = querySolver(query);
|
||||||
|
|
||||||
CheckResult result;
|
CheckResult result;
|
||||||
// TODO proper parsing
|
// TODO proper parsing
|
||||||
@ -108,7 +107,7 @@ tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> CHCSmtLib2Interface
|
|||||||
return {result, Expression(true), {}};
|
return {result, Expression(true), {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHCSmtLib2Interface::declareVariable(string const& _name, SortPointer const& _sort)
|
void CHCSmtLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort);
|
smtAssert(_sort);
|
||||||
if (_sort->kind == Kind::Function)
|
if (_sort->kind == Kind::Function)
|
||||||
@ -120,25 +119,25 @@ void CHCSmtLib2Interface::declareVariable(string const& _name, SortPointer const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string CHCSmtLib2Interface::toSmtLibSort(Sort const& _sort)
|
std::string CHCSmtLib2Interface::toSmtLibSort(Sort const& _sort)
|
||||||
{
|
{
|
||||||
if (!m_sortNames.count(&_sort))
|
if (!m_sortNames.count(&_sort))
|
||||||
m_sortNames[&_sort] = m_smtlib2->toSmtLibSort(_sort);
|
m_sortNames[&_sort] = m_smtlib2->toSmtLibSort(_sort);
|
||||||
return m_sortNames.at(&_sort);
|
return m_sortNames.at(&_sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
string CHCSmtLib2Interface::toSmtLibSort(vector<SortPointer> const& _sorts)
|
std::string CHCSmtLib2Interface::toSmtLibSort(std::vector<SortPointer> const& _sorts)
|
||||||
{
|
{
|
||||||
string ssort("(");
|
std::string ssort("(");
|
||||||
for (auto const& sort: _sorts)
|
for (auto const& sort: _sorts)
|
||||||
ssort += toSmtLibSort(*sort) + " ";
|
ssort += toSmtLibSort(*sort) + " ";
|
||||||
ssort += ")";
|
ssort += ")";
|
||||||
return ssort;
|
return ssort;
|
||||||
}
|
}
|
||||||
|
|
||||||
string CHCSmtLib2Interface::forall()
|
std::string CHCSmtLib2Interface::forall()
|
||||||
{
|
{
|
||||||
string vars("(");
|
std::string vars("(");
|
||||||
for (auto const& [name, sort]: m_smtlib2->variables())
|
for (auto const& [name, sort]: m_smtlib2->variables())
|
||||||
{
|
{
|
||||||
solAssert(sort, "");
|
solAssert(sort, "");
|
||||||
@ -149,17 +148,17 @@ string CHCSmtLib2Interface::forall()
|
|||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHCSmtLib2Interface::declareFunction(string const& _name, SortPointer const& _sort)
|
void CHCSmtLib2Interface::declareFunction(std::string const& _name, SortPointer const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort);
|
smtAssert(_sort);
|
||||||
smtAssert(_sort->kind == Kind::Function);
|
smtAssert(_sort->kind == Kind::Function);
|
||||||
// TODO Use domain and codomain as key as well
|
// TODO Use domain and codomain as key as well
|
||||||
if (!m_variables.count(_name))
|
if (!m_variables.count(_name))
|
||||||
{
|
{
|
||||||
auto fSort = dynamic_pointer_cast<FunctionSort>(_sort);
|
auto fSort = std::dynamic_pointer_cast<FunctionSort>(_sort);
|
||||||
smtAssert(fSort->codomain);
|
smtAssert(fSort->codomain);
|
||||||
string domain = toSmtLibSort(fSort->domain);
|
std::string domain = toSmtLibSort(fSort->domain);
|
||||||
string codomain = toSmtLibSort(*fSort->codomain);
|
std::string codomain = toSmtLibSort(*fSort->codomain);
|
||||||
m_variables.insert(_name);
|
m_variables.insert(_name);
|
||||||
write(
|
write(
|
||||||
"(declare-fun |" +
|
"(declare-fun |" +
|
||||||
@ -173,12 +172,12 @@ void CHCSmtLib2Interface::declareFunction(string const& _name, SortPointer const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHCSmtLib2Interface::write(string _data)
|
void CHCSmtLib2Interface::write(std::string _data)
|
||||||
{
|
{
|
||||||
m_accumulatedOutput += std::move(_data) + "\n";
|
m_accumulatedOutput += std::move(_data) + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
string CHCSmtLib2Interface::querySolver(string const& _input)
|
std::string CHCSmtLib2Interface::querySolver(std::string const& _input)
|
||||||
{
|
{
|
||||||
util::h256 inputHash = util::keccak256(_input);
|
util::h256 inputHash = util::keccak256(_input);
|
||||||
if (m_queryResponses.count(inputHash))
|
if (m_queryResponses.count(inputHash))
|
||||||
@ -212,7 +211,7 @@ std::string CHCSmtLib2Interface::dumpQuery(Expression const& _expr)
|
|||||||
std::string CHCSmtLib2Interface::createHeaderAndDeclarations() {
|
std::string CHCSmtLib2Interface::createHeaderAndDeclarations() {
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
if (m_queryTimeout)
|
if (m_queryTimeout)
|
||||||
s << "(set-option :timeout " + to_string(*m_queryTimeout) + ")\n";
|
s << "(set-option :timeout " + std::to_string(*m_queryTimeout) + ")\n";
|
||||||
s << "(set-logic HORN)" << std::endl;
|
s << "(set-logic HORN)" << std::endl;
|
||||||
|
|
||||||
for (auto const& decl: m_smtlib2->userSorts() | ranges::views::values)
|
for (auto const& decl: m_smtlib2->userSorts() | ranges::views::values)
|
||||||
|
@ -23,12 +23,11 @@
|
|||||||
|
|
||||||
#include <cvc4/util/bitvector.h>
|
#include <cvc4/util/bitvector.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::smtutil;
|
using namespace solidity::smtutil;
|
||||||
|
|
||||||
CVC4Interface::CVC4Interface(optional<unsigned> _queryTimeout):
|
CVC4Interface::CVC4Interface(std::optional<unsigned> _queryTimeout):
|
||||||
SolverInterface(_queryTimeout),
|
SolverInterface(_queryTimeout),
|
||||||
m_solver(&m_context)
|
m_solver(&m_context)
|
||||||
{
|
{
|
||||||
@ -56,7 +55,7 @@ void CVC4Interface::pop()
|
|||||||
m_solver.pop();
|
m_solver.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVC4Interface::declareVariable(string const& _name, SortPointer const& _sort)
|
void CVC4Interface::declareVariable(std::string const& _name, SortPointer const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort, "");
|
smtAssert(_sort, "");
|
||||||
m_variables[_name] = m_context.mkVar(_name.c_str(), cvc4Sort(*_sort));
|
m_variables[_name] = m_context.mkVar(_name.c_str(), cvc4Sort(*_sort));
|
||||||
@ -86,10 +85,10 @@ void CVC4Interface::addAssertion(Expression const& _expr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const& _expressionsToEvaluate)
|
std::pair<CheckResult, std::vector<std::string>> CVC4Interface::check(std::vector<Expression> const& _expressionsToEvaluate)
|
||||||
{
|
{
|
||||||
CheckResult result;
|
CheckResult result;
|
||||||
vector<string> values;
|
std::vector<std::string> values;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (m_solver.checkSat().isSat())
|
switch (m_solver.checkSat().isSat())
|
||||||
@ -119,7 +118,7 @@ pair<CheckResult, vector<string>> CVC4Interface::check(vector<Expression> const&
|
|||||||
values.clear();
|
values.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_pair(result, values);
|
return std::make_pair(result, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
|
CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
|
||||||
@ -128,13 +127,13 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
|
|||||||
if (_expr.arguments.empty() && m_variables.count(_expr.name))
|
if (_expr.arguments.empty() && m_variables.count(_expr.name))
|
||||||
return m_variables.at(_expr.name);
|
return m_variables.at(_expr.name);
|
||||||
|
|
||||||
vector<CVC4::Expr> arguments;
|
std::vector<CVC4::Expr> arguments;
|
||||||
for (auto const& arg: _expr.arguments)
|
for (auto const& arg: _expr.arguments)
|
||||||
arguments.push_back(toCVC4Expr(arg));
|
arguments.push_back(toCVC4Expr(arg));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string const& n = _expr.name;
|
std::string const& n = _expr.name;
|
||||||
// Function application
|
// Function application
|
||||||
if (!arguments.empty() && m_variables.count(_expr.name))
|
if (!arguments.empty() && m_variables.count(_expr.name))
|
||||||
return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments);
|
return m_context.mkExpr(CVC4::kind::APPLY_UF, m_variables.at(n), arguments);
|
||||||
@ -145,7 +144,7 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
|
|||||||
return m_context.mkConst(true);
|
return m_context.mkConst(true);
|
||||||
else if (n == "false")
|
else if (n == "false")
|
||||||
return m_context.mkConst(false);
|
return m_context.mkConst(false);
|
||||||
else if (auto sortSort = dynamic_pointer_cast<SortSort>(_expr.sort))
|
else if (auto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.sort))
|
||||||
return m_context.mkVar(n, cvc4Sort(*sortSort->inner));
|
return m_context.mkVar(n, cvc4Sort(*sortSort->inner));
|
||||||
else
|
else
|
||||||
try
|
try
|
||||||
@ -224,7 +223,7 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
|
|||||||
}
|
}
|
||||||
else if (n == "bv2int")
|
else if (n == "bv2int")
|
||||||
{
|
{
|
||||||
auto intSort = dynamic_pointer_cast<IntSort>(_expr.sort);
|
auto intSort = std::dynamic_pointer_cast<IntSort>(_expr.sort);
|
||||||
smtAssert(intSort, "");
|
smtAssert(intSort, "");
|
||||||
auto nat = m_context.mkExpr(CVC4::kind::BITVECTOR_TO_NAT, arguments[0]);
|
auto nat = m_context.mkExpr(CVC4::kind::BITVECTOR_TO_NAT, arguments[0]);
|
||||||
if (!intSort->isSigned)
|
if (!intSort->isSigned)
|
||||||
@ -254,13 +253,13 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
|
|||||||
return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]);
|
return m_context.mkExpr(CVC4::kind::STORE, arguments[0], arguments[1], arguments[2]);
|
||||||
else if (n == "const_array")
|
else if (n == "const_array")
|
||||||
{
|
{
|
||||||
shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort);
|
std::shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort);
|
||||||
smtAssert(sortSort, "");
|
smtAssert(sortSort, "");
|
||||||
return m_context.mkConst(CVC4::ArrayStoreAll(cvc4Sort(*sortSort->inner), arguments[1]));
|
return m_context.mkConst(CVC4::ArrayStoreAll(cvc4Sort(*sortSort->inner), arguments[1]));
|
||||||
}
|
}
|
||||||
else if (n == "tuple_get")
|
else if (n == "tuple_get")
|
||||||
{
|
{
|
||||||
shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments[0].sort);
|
std::shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments[0].sort);
|
||||||
smtAssert(tupleSort, "");
|
smtAssert(tupleSort, "");
|
||||||
CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components));
|
CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components));
|
||||||
CVC4::Datatype const& dt = tt.getDatatype();
|
CVC4::Datatype const& dt = tt.getDatatype();
|
||||||
@ -270,7 +269,7 @@ CVC4::Expr CVC4Interface::toCVC4Expr(Expression const& _expr)
|
|||||||
}
|
}
|
||||||
else if (n == "tuple_constructor")
|
else if (n == "tuple_constructor")
|
||||||
{
|
{
|
||||||
shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort);
|
std::shared_ptr<TupleSort> tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort);
|
||||||
smtAssert(tupleSort, "");
|
smtAssert(tupleSort, "");
|
||||||
CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components));
|
CVC4::DatatypeType tt = m_context.mkTupleType(cvc4Sort(tupleSort->components));
|
||||||
CVC4::Datatype const& dt = tt.getDatatype();
|
CVC4::Datatype const& dt = tt.getDatatype();
|
||||||
@ -328,9 +327,9 @@ CVC4::Type CVC4Interface::cvc4Sort(Sort const& _sort)
|
|||||||
return m_context.integerType();
|
return m_context.integerType();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<CVC4::Type> CVC4Interface::cvc4Sort(vector<SortPointer> const& _sorts)
|
std::vector<CVC4::Type> CVC4Interface::cvc4Sort(std::vector<SortPointer> const& _sorts)
|
||||||
{
|
{
|
||||||
vector<CVC4::Type> cvc4Sorts;
|
std::vector<CVC4::Type> cvc4Sorts;
|
||||||
for (auto const& _sort: _sorts)
|
for (auto const& _sort: _sorts)
|
||||||
cvc4Sorts.push_back(cvc4Sort(*_sort));
|
cvc4Sorts.push_back(cvc4Sort(*_sort));
|
||||||
return cvc4Sorts;
|
return cvc4Sorts;
|
||||||
|
@ -33,16 +33,15 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
using namespace solidity::smtutil;
|
using namespace solidity::smtutil;
|
||||||
|
|
||||||
SMTLib2Interface::SMTLib2Interface(
|
SMTLib2Interface::SMTLib2Interface(
|
||||||
map<h256, string> _queryResponses,
|
std::map<h256, std::string> _queryResponses,
|
||||||
ReadCallback::Callback _smtCallback,
|
ReadCallback::Callback _smtCallback,
|
||||||
optional<unsigned> _queryTimeout
|
std::optional<unsigned> _queryTimeout
|
||||||
):
|
):
|
||||||
SolverInterface(_queryTimeout),
|
SolverInterface(_queryTimeout),
|
||||||
m_queryResponses(std::move(_queryResponses)),
|
m_queryResponses(std::move(_queryResponses)),
|
||||||
@ -59,7 +58,7 @@ void SMTLib2Interface::reset()
|
|||||||
m_userSorts.clear();
|
m_userSorts.clear();
|
||||||
write("(set-option :produce-models true)");
|
write("(set-option :produce-models true)");
|
||||||
if (m_queryTimeout)
|
if (m_queryTimeout)
|
||||||
write("(set-option :timeout " + to_string(*m_queryTimeout) + ")");
|
write("(set-option :timeout " + std::to_string(*m_queryTimeout) + ")");
|
||||||
write("(set-logic ALL)");
|
write("(set-logic ALL)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ void SMTLib2Interface::pop()
|
|||||||
m_accumulatedOutput.pop_back();
|
m_accumulatedOutput.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTLib2Interface::declareVariable(string const& _name, SortPointer const& _sort)
|
void SMTLib2Interface::declareVariable(std::string const& _name, SortPointer const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort, "");
|
smtAssert(_sort, "");
|
||||||
if (_sort->kind == Kind::Function)
|
if (_sort->kind == Kind::Function)
|
||||||
@ -86,16 +85,16 @@ void SMTLib2Interface::declareVariable(string const& _name, SortPointer const& _
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTLib2Interface::declareFunction(string const& _name, SortPointer const& _sort)
|
void SMTLib2Interface::declareFunction(std::string const& _name, SortPointer const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort, "");
|
smtAssert(_sort, "");
|
||||||
smtAssert(_sort->kind == Kind::Function, "");
|
smtAssert(_sort->kind == Kind::Function, "");
|
||||||
// TODO Use domain and codomain as key as well
|
// TODO Use domain and codomain as key as well
|
||||||
if (!m_variables.count(_name))
|
if (!m_variables.count(_name))
|
||||||
{
|
{
|
||||||
auto const& fSort = dynamic_pointer_cast<FunctionSort>(_sort);
|
auto const& fSort = std::dynamic_pointer_cast<FunctionSort>(_sort);
|
||||||
string domain = toSmtLibSort(fSort->domain);
|
std::string domain = toSmtLibSort(fSort->domain);
|
||||||
string codomain = toSmtLibSort(*fSort->codomain);
|
std::string codomain = toSmtLibSort(*fSort->codomain);
|
||||||
m_variables.emplace(_name, _sort);
|
m_variables.emplace(_name, _sort);
|
||||||
write(
|
write(
|
||||||
"(declare-fun |" +
|
"(declare-fun |" +
|
||||||
@ -114,9 +113,9 @@ void SMTLib2Interface::addAssertion(Expression const& _expr)
|
|||||||
write("(assert " + toSExpr(_expr) + ")");
|
write("(assert " + toSExpr(_expr) + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<CheckResult, vector<string>> SMTLib2Interface::check(vector<Expression> const& _expressionsToEvaluate)
|
std::pair<CheckResult, std::vector<std::string>> SMTLib2Interface::check(std::vector<Expression> const& _expressionsToEvaluate)
|
||||||
{
|
{
|
||||||
string response = querySolver(
|
std::string response = querySolver(
|
||||||
boost::algorithm::join(m_accumulatedOutput, "\n") +
|
boost::algorithm::join(m_accumulatedOutput, "\n") +
|
||||||
checkSatAndGetValuesCommand(_expressionsToEvaluate)
|
checkSatAndGetValuesCommand(_expressionsToEvaluate)
|
||||||
);
|
);
|
||||||
@ -132,13 +131,13 @@ pair<CheckResult, vector<string>> SMTLib2Interface::check(vector<Expression> con
|
|||||||
else
|
else
|
||||||
result = CheckResult::ERROR;
|
result = CheckResult::ERROR;
|
||||||
|
|
||||||
vector<string> values;
|
std::vector<std::string> values;
|
||||||
if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty())
|
if (result == CheckResult::SATISFIABLE && !_expressionsToEvaluate.empty())
|
||||||
values = parseValues(find(response.cbegin(), response.cend(), '\n'), response.cend());
|
values = parseValues(find(response.cbegin(), response.cend(), '\n'), response.cend());
|
||||||
return make_pair(result, values);
|
return std::make_pair(result, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
string SMTLib2Interface::toSExpr(Expression const& _expr)
|
std::string SMTLib2Interface::toSExpr(Expression const& _expr)
|
||||||
{
|
{
|
||||||
if (_expr.arguments.empty())
|
if (_expr.arguments.empty())
|
||||||
return _expr.name;
|
return _expr.name;
|
||||||
@ -148,16 +147,16 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
|
|||||||
{
|
{
|
||||||
size_t size = std::stoul(_expr.arguments[1].name);
|
size_t size = std::stoul(_expr.arguments[1].name);
|
||||||
auto arg = toSExpr(_expr.arguments.front());
|
auto arg = toSExpr(_expr.arguments.front());
|
||||||
auto int2bv = "(_ int2bv " + to_string(size) + ")";
|
auto int2bv = "(_ int2bv " + std::to_string(size) + ")";
|
||||||
// Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed.
|
// Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed.
|
||||||
sexpr += string("ite ") +
|
sexpr += std::string("ite ") +
|
||||||
"(>= " + arg + " 0) " +
|
"(>= " + arg + " 0) " +
|
||||||
"(" + int2bv + " " + arg + ") " +
|
"(" + int2bv + " " + arg + ") " +
|
||||||
"(bvneg (" + int2bv + " (- " + arg + ")))";
|
"(bvneg (" + int2bv + " (- " + arg + ")))";
|
||||||
}
|
}
|
||||||
else if (_expr.name == "bv2int")
|
else if (_expr.name == "bv2int")
|
||||||
{
|
{
|
||||||
auto intSort = dynamic_pointer_cast<IntSort>(_expr.sort);
|
auto intSort = std::dynamic_pointer_cast<IntSort>(_expr.sort);
|
||||||
smtAssert(intSort, "");
|
smtAssert(intSort, "");
|
||||||
|
|
||||||
auto arg = toSExpr(_expr.arguments.front());
|
auto arg = toSExpr(_expr.arguments.front());
|
||||||
@ -166,13 +165,13 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
|
|||||||
if (!intSort->isSigned)
|
if (!intSort->isSigned)
|
||||||
return nat;
|
return nat;
|
||||||
|
|
||||||
auto bvSort = dynamic_pointer_cast<BitVectorSort>(_expr.arguments.front().sort);
|
auto bvSort = std::dynamic_pointer_cast<BitVectorSort>(_expr.arguments.front().sort);
|
||||||
smtAssert(bvSort, "");
|
smtAssert(bvSort, "");
|
||||||
auto size = to_string(bvSort->size);
|
auto size = std::to_string(bvSort->size);
|
||||||
auto pos = to_string(bvSort->size - 1);
|
auto pos = std::to_string(bvSort->size - 1);
|
||||||
|
|
||||||
// Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed.
|
// Some solvers treat all BVs as unsigned, so we need to manually apply 2's complement if needed.
|
||||||
sexpr += string("ite ") +
|
sexpr += std::string("ite ") +
|
||||||
"(= ((_ extract " + pos + " " + pos + ")" + arg + ") #b0) " +
|
"(= ((_ extract " + pos + " " + pos + ")" + arg + ") #b0) " +
|
||||||
nat + " " +
|
nat + " " +
|
||||||
"(- (bv2nat (bvneg " + arg + ")))";
|
"(- (bv2nat (bvneg " + arg + ")))";
|
||||||
@ -182,7 +181,7 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
|
|||||||
smtAssert(_expr.arguments.size() == 2, "");
|
smtAssert(_expr.arguments.size() == 2, "");
|
||||||
auto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments.at(0).sort);
|
auto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments.at(0).sort);
|
||||||
smtAssert(sortSort, "");
|
smtAssert(sortSort, "");
|
||||||
auto arraySort = dynamic_pointer_cast<ArraySort>(sortSort->inner);
|
auto arraySort = std::dynamic_pointer_cast<ArraySort>(sortSort->inner);
|
||||||
smtAssert(arraySort, "");
|
smtAssert(arraySort, "");
|
||||||
sexpr += "(as const " + toSmtLibSort(*arraySort) + ") ";
|
sexpr += "(as const " + toSmtLibSort(*arraySort) + ") ";
|
||||||
sexpr += toSExpr(_expr.arguments.at(1));
|
sexpr += toSExpr(_expr.arguments.at(1));
|
||||||
@ -190,14 +189,14 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
|
|||||||
else if (_expr.name == "tuple_get")
|
else if (_expr.name == "tuple_get")
|
||||||
{
|
{
|
||||||
smtAssert(_expr.arguments.size() == 2, "");
|
smtAssert(_expr.arguments.size() == 2, "");
|
||||||
auto tupleSort = dynamic_pointer_cast<TupleSort>(_expr.arguments.at(0).sort);
|
auto tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.arguments.at(0).sort);
|
||||||
size_t index = std::stoul(_expr.arguments.at(1).name);
|
size_t index = std::stoul(_expr.arguments.at(1).name);
|
||||||
smtAssert(index < tupleSort->members.size(), "");
|
smtAssert(index < tupleSort->members.size(), "");
|
||||||
sexpr += "|" + tupleSort->members.at(index) + "| " + toSExpr(_expr.arguments.at(0));
|
sexpr += "|" + tupleSort->members.at(index) + "| " + toSExpr(_expr.arguments.at(0));
|
||||||
}
|
}
|
||||||
else if (_expr.name == "tuple_constructor")
|
else if (_expr.name == "tuple_constructor")
|
||||||
{
|
{
|
||||||
auto tupleSort = dynamic_pointer_cast<TupleSort>(_expr.sort);
|
auto tupleSort = std::dynamic_pointer_cast<TupleSort>(_expr.sort);
|
||||||
smtAssert(tupleSort, "");
|
smtAssert(tupleSort, "");
|
||||||
sexpr += "|" + tupleSort->name + "|";
|
sexpr += "|" + tupleSort->name + "|";
|
||||||
for (auto const& arg: _expr.arguments)
|
for (auto const& arg: _expr.arguments)
|
||||||
@ -213,7 +212,7 @@ string SMTLib2Interface::toSExpr(Expression const& _expr)
|
|||||||
return sexpr;
|
return sexpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
|
std::string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
|
||||||
{
|
{
|
||||||
switch (_sort.kind)
|
switch (_sort.kind)
|
||||||
{
|
{
|
||||||
@ -222,7 +221,7 @@ string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
|
|||||||
case Kind::Bool:
|
case Kind::Bool:
|
||||||
return "Bool";
|
return "Bool";
|
||||||
case Kind::BitVector:
|
case Kind::BitVector:
|
||||||
return "(_ BitVec " + to_string(dynamic_cast<BitVectorSort const&>(_sort).size) + ")";
|
return "(_ BitVec " + std::to_string(dynamic_cast<BitVectorSort const&>(_sort).size) + ")";
|
||||||
case Kind::Array:
|
case Kind::Array:
|
||||||
{
|
{
|
||||||
auto const& arraySort = dynamic_cast<ArraySort const&>(_sort);
|
auto const& arraySort = dynamic_cast<ArraySort const&>(_sort);
|
||||||
@ -232,11 +231,11 @@ string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
|
|||||||
case Kind::Tuple:
|
case Kind::Tuple:
|
||||||
{
|
{
|
||||||
auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort);
|
auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort);
|
||||||
string tupleName = "|" + tupleSort.name + "|";
|
std::string tupleName = "|" + tupleSort.name + "|";
|
||||||
auto isName = [&](auto entry) { return entry.first == tupleName; };
|
auto isName = [&](auto entry) { return entry.first == tupleName; };
|
||||||
if (ranges::find_if(m_userSorts, isName) == m_userSorts.end())
|
if (ranges::find_if(m_userSorts, isName) == m_userSorts.end())
|
||||||
{
|
{
|
||||||
string decl("(declare-datatypes ((" + tupleName + " 0)) (((" + tupleName);
|
std::string decl("(declare-datatypes ((" + tupleName + " 0)) (((" + tupleName);
|
||||||
smtAssert(tupleSort.members.size() == tupleSort.components.size(), "");
|
smtAssert(tupleSort.members.size() == tupleSort.components.size(), "");
|
||||||
for (unsigned i = 0; i < tupleSort.members.size(); ++i)
|
for (unsigned i = 0; i < tupleSort.members.size(); ++i)
|
||||||
decl += " (|" + tupleSort.members.at(i) + "| " + toSmtLibSort(*tupleSort.components.at(i)) + ")";
|
decl += " (|" + tupleSort.members.at(i) + "| " + toSmtLibSort(*tupleSort.components.at(i)) + ")";
|
||||||
@ -252,24 +251,24 @@ string SMTLib2Interface::toSmtLibSort(Sort const& _sort)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string SMTLib2Interface::toSmtLibSort(vector<SortPointer> const& _sorts)
|
std::string SMTLib2Interface::toSmtLibSort(std::vector<SortPointer> const& _sorts)
|
||||||
{
|
{
|
||||||
string ssort("(");
|
std::string ssort("(");
|
||||||
for (auto const& sort: _sorts)
|
for (auto const& sort: _sorts)
|
||||||
ssort += toSmtLibSort(*sort) + " ";
|
ssort += toSmtLibSort(*sort) + " ";
|
||||||
ssort += ")";
|
ssort += ")";
|
||||||
return ssort;
|
return ssort;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTLib2Interface::write(string _data)
|
void SMTLib2Interface::write(std::string _data)
|
||||||
{
|
{
|
||||||
smtAssert(!m_accumulatedOutput.empty(), "");
|
smtAssert(!m_accumulatedOutput.empty(), "");
|
||||||
m_accumulatedOutput.back() += std::move(_data) + "\n";
|
m_accumulatedOutput.back() += std::move(_data) + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
string SMTLib2Interface::checkSatAndGetValuesCommand(vector<Expression> const& _expressionsToEvaluate)
|
std::string SMTLib2Interface::checkSatAndGetValuesCommand(std::vector<Expression> const& _expressionsToEvaluate)
|
||||||
{
|
{
|
||||||
string command;
|
std::string command;
|
||||||
if (_expressionsToEvaluate.empty())
|
if (_expressionsToEvaluate.empty())
|
||||||
command = "(check-sat)\n";
|
command = "(check-sat)\n";
|
||||||
else
|
else
|
||||||
@ -279,22 +278,22 @@ string SMTLib2Interface::checkSatAndGetValuesCommand(vector<Expression> const& _
|
|||||||
{
|
{
|
||||||
auto const& e = _expressionsToEvaluate.at(i);
|
auto const& e = _expressionsToEvaluate.at(i);
|
||||||
smtAssert(e.sort->kind == Kind::Int || e.sort->kind == Kind::Bool, "Invalid sort for expression to evaluate.");
|
smtAssert(e.sort->kind == Kind::Int || e.sort->kind == Kind::Bool, "Invalid sort for expression to evaluate.");
|
||||||
command += "(declare-const |EVALEXPR_" + to_string(i) + "| " + (e.sort->kind == Kind::Int ? "Int" : "Bool") + ")\n";
|
command += "(declare-const |EVALEXPR_" + std::to_string(i) + "| " + (e.sort->kind == Kind::Int ? "Int" : "Bool") + ")\n";
|
||||||
command += "(assert (= |EVALEXPR_" + to_string(i) + "| " + toSExpr(e) + "))\n";
|
command += "(assert (= |EVALEXPR_" + std::to_string(i) + "| " + toSExpr(e) + "))\n";
|
||||||
}
|
}
|
||||||
command += "(check-sat)\n";
|
command += "(check-sat)\n";
|
||||||
command += "(get-value (";
|
command += "(get-value (";
|
||||||
for (size_t i = 0; i < _expressionsToEvaluate.size(); i++)
|
for (size_t i = 0; i < _expressionsToEvaluate.size(); i++)
|
||||||
command += "|EVALEXPR_" + to_string(i) + "| ";
|
command += "|EVALEXPR_" + std::to_string(i) + "| ";
|
||||||
command += "))\n";
|
command += "))\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> SMTLib2Interface::parseValues(string::const_iterator _start, string::const_iterator _end)
|
std::vector<std::string> SMTLib2Interface::parseValues(std::string::const_iterator _start, std::string::const_iterator _end)
|
||||||
{
|
{
|
||||||
vector<string> values;
|
std::vector<std::string> values;
|
||||||
while (_start < _end)
|
while (_start < _end)
|
||||||
{
|
{
|
||||||
auto valStart = find(_start, _end, ' ');
|
auto valStart = find(_start, _end, ' ');
|
||||||
@ -308,7 +307,7 @@ vector<string> SMTLib2Interface::parseValues(string::const_iterator _start, stri
|
|||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
string SMTLib2Interface::querySolver(string const& _input)
|
std::string SMTLib2Interface::querySolver(std::string const& _input)
|
||||||
{
|
{
|
||||||
h256 inputHash = keccak256(_input);
|
h256 inputHash = keccak256(_input);
|
||||||
if (m_queryResponses.count(inputHash))
|
if (m_queryResponses.count(inputHash))
|
||||||
@ -323,7 +322,7 @@ string SMTLib2Interface::querySolver(string const& _input)
|
|||||||
return "unknown\n";
|
return "unknown\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
string SMTLib2Interface::dumpQuery(vector<Expression> const& _expressionsToEvaluate)
|
std::string SMTLib2Interface::dumpQuery(std::vector<Expression> const& _expressionsToEvaluate)
|
||||||
{
|
{
|
||||||
return boost::algorithm::join(m_accumulatedOutput, "\n") +
|
return boost::algorithm::join(m_accumulatedOutput, "\n") +
|
||||||
checkSatAndGetValuesCommand(_expressionsToEvaluate);
|
checkSatAndGetValuesCommand(_expressionsToEvaluate);
|
||||||
|
@ -26,31 +26,30 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <libsmtutil/SMTLib2Interface.h>
|
#include <libsmtutil/SMTLib2Interface.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::frontend;
|
using namespace solidity::frontend;
|
||||||
using namespace solidity::smtutil;
|
using namespace solidity::smtutil;
|
||||||
|
|
||||||
SMTPortfolio::SMTPortfolio(
|
SMTPortfolio::SMTPortfolio(
|
||||||
map<h256, string> _smtlib2Responses,
|
std::map<h256, std::string> _smtlib2Responses,
|
||||||
frontend::ReadCallback::Callback _smtCallback,
|
frontend::ReadCallback::Callback _smtCallback,
|
||||||
[[maybe_unused]] SMTSolverChoice _enabledSolvers,
|
[[maybe_unused]] SMTSolverChoice _enabledSolvers,
|
||||||
optional<unsigned> _queryTimeout,
|
std::optional<unsigned> _queryTimeout,
|
||||||
bool _printQuery
|
bool _printQuery
|
||||||
):
|
):
|
||||||
SolverInterface(_queryTimeout)
|
SolverInterface(_queryTimeout)
|
||||||
{
|
{
|
||||||
solAssert(!_printQuery || _enabledSolvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries");
|
solAssert(!_printQuery || _enabledSolvers == smtutil::SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries");
|
||||||
if (_enabledSolvers.smtlib2)
|
if (_enabledSolvers.smtlib2)
|
||||||
m_solvers.emplace_back(make_unique<SMTLib2Interface>(std::move(_smtlib2Responses), std::move(_smtCallback), m_queryTimeout));
|
m_solvers.emplace_back(std::make_unique<SMTLib2Interface>(std::move(_smtlib2Responses), std::move(_smtCallback), m_queryTimeout));
|
||||||
#ifdef HAVE_Z3
|
#ifdef HAVE_Z3
|
||||||
if (_enabledSolvers.z3 && Z3Interface::available())
|
if (_enabledSolvers.z3 && Z3Interface::available())
|
||||||
m_solvers.emplace_back(make_unique<Z3Interface>(m_queryTimeout));
|
m_solvers.emplace_back(std::make_unique<Z3Interface>(m_queryTimeout));
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CVC4
|
#ifdef HAVE_CVC4
|
||||||
if (_enabledSolvers.cvc4)
|
if (_enabledSolvers.cvc4)
|
||||||
m_solvers.emplace_back(make_unique<CVC4Interface>(m_queryTimeout));
|
m_solvers.emplace_back(std::make_unique<CVC4Interface>(m_queryTimeout));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +71,7 @@ void SMTPortfolio::pop()
|
|||||||
s->pop();
|
s->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTPortfolio::declareVariable(string const& _name, SortPointer const& _sort)
|
void SMTPortfolio::declareVariable(std::string const& _name, SortPointer const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort, "");
|
smtAssert(_sort, "");
|
||||||
for (auto const& s: m_solvers)
|
for (auto const& s: m_solvers)
|
||||||
@ -115,14 +114,14 @@ void SMTPortfolio::addAssertion(Expression const& _expr)
|
|||||||
*
|
*
|
||||||
* If all solvers return ERROR, the result is ERROR.
|
* If all solvers return ERROR, the result is ERROR.
|
||||||
*/
|
*/
|
||||||
pair<CheckResult, vector<string>> SMTPortfolio::check(vector<Expression> const& _expressionsToEvaluate)
|
std::pair<CheckResult, std::vector<std::string>> SMTPortfolio::check(std::vector<Expression> const& _expressionsToEvaluate)
|
||||||
{
|
{
|
||||||
CheckResult lastResult = CheckResult::ERROR;
|
CheckResult lastResult = CheckResult::ERROR;
|
||||||
vector<string> finalValues;
|
std::vector<std::string> finalValues;
|
||||||
for (auto const& s: m_solvers)
|
for (auto const& s: m_solvers)
|
||||||
{
|
{
|
||||||
CheckResult result;
|
CheckResult result;
|
||||||
vector<string> values;
|
std::vector<std::string> values;
|
||||||
tie(result, values) = s->check(_expressionsToEvaluate);
|
tie(result, values) = s->check(_expressionsToEvaluate);
|
||||||
if (solverAnswered(result))
|
if (solverAnswered(result))
|
||||||
{
|
{
|
||||||
@ -140,10 +139,10 @@ pair<CheckResult, vector<string>> SMTPortfolio::check(vector<Expression> const&
|
|||||||
else if (result == CheckResult::UNKNOWN && lastResult == CheckResult::ERROR)
|
else if (result == CheckResult::UNKNOWN && lastResult == CheckResult::ERROR)
|
||||||
lastResult = result;
|
lastResult = result;
|
||||||
}
|
}
|
||||||
return make_pair(lastResult, finalValues);
|
return std::make_pair(lastResult, finalValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> SMTPortfolio::unhandledQueries()
|
std::vector<std::string> SMTPortfolio::unhandledQueries()
|
||||||
{
|
{
|
||||||
// This code assumes that the constructor guarantees that
|
// This code assumes that the constructor guarantees that
|
||||||
// SmtLib2Interface is in position 0, if enabled.
|
// SmtLib2Interface is in position 0, if enabled.
|
||||||
@ -158,7 +157,7 @@ bool SMTPortfolio::solverAnswered(CheckResult result)
|
|||||||
return result == CheckResult::SATISFIABLE || result == CheckResult::UNSATISFIABLE;
|
return result == CheckResult::SATISFIABLE || result == CheckResult::UNSATISFIABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
string SMTPortfolio::dumpQuery(vector<Expression> const& _expressionsToEvaluate)
|
std::string SMTPortfolio::dumpQuery(std::vector<Expression> const& _expressionsToEvaluate)
|
||||||
{
|
{
|
||||||
// This code assumes that the constructor guarantees that
|
// This code assumes that the constructor guarantees that
|
||||||
// SmtLib2Interface is in position 0, if enabled.
|
// SmtLib2Interface is in position 0, if enabled.
|
||||||
|
@ -19,22 +19,20 @@
|
|||||||
|
|
||||||
#include <libsmtutil/Sorts.h>
|
#include <libsmtutil/Sorts.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace solidity::smtutil
|
namespace solidity::smtutil
|
||||||
{
|
{
|
||||||
|
|
||||||
shared_ptr<Sort> const SortProvider::boolSort{make_shared<Sort>(Kind::Bool)};
|
std::shared_ptr<Sort> const SortProvider::boolSort{std::make_shared<Sort>(Kind::Bool)};
|
||||||
shared_ptr<IntSort> const SortProvider::uintSort{make_shared<IntSort>(false)};
|
std::shared_ptr<IntSort> const SortProvider::uintSort{std::make_shared<IntSort>(false)};
|
||||||
shared_ptr<IntSort> const SortProvider::sintSort{make_shared<IntSort>(true)};
|
std::shared_ptr<IntSort> const SortProvider::sintSort{std::make_shared<IntSort>(true)};
|
||||||
|
|
||||||
shared_ptr<IntSort> SortProvider::intSort(bool _signed)
|
std::shared_ptr<IntSort> SortProvider::intSort(bool _signed)
|
||||||
{
|
{
|
||||||
if (_signed)
|
if (_signed)
|
||||||
return sintSort;
|
return sintSort;
|
||||||
return uintSort;
|
return uintSort;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<BitVectorSort> const SortProvider::bitVectorSort{make_shared<BitVectorSort>(256)};
|
std::shared_ptr<BitVectorSort> const SortProvider::bitVectorSort{std::make_shared<BitVectorSort>(256)};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,21 +23,20 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::smtutil;
|
using namespace solidity::smtutil;
|
||||||
|
|
||||||
Z3CHCInterface::Z3CHCInterface(optional<unsigned> _queryTimeout):
|
Z3CHCInterface::Z3CHCInterface(std::optional<unsigned> _queryTimeout):
|
||||||
CHCSolverInterface(_queryTimeout),
|
CHCSolverInterface(_queryTimeout),
|
||||||
m_z3Interface(make_unique<Z3Interface>(m_queryTimeout)),
|
m_z3Interface(std::make_unique<Z3Interface>(m_queryTimeout)),
|
||||||
m_context(m_z3Interface->context()),
|
m_context(m_z3Interface->context()),
|
||||||
m_solver(*m_context)
|
m_solver(*m_context)
|
||||||
{
|
{
|
||||||
Z3_get_version(
|
Z3_get_version(
|
||||||
&get<0>(m_version),
|
&std::get<0>(m_version),
|
||||||
&get<1>(m_version),
|
&std::get<1>(m_version),
|
||||||
&get<2>(m_version),
|
&std::get<2>(m_version),
|
||||||
&get<3>(m_version)
|
&std::get<3>(m_version)
|
||||||
);
|
);
|
||||||
|
|
||||||
// These need to be set globally.
|
// These need to be set globally.
|
||||||
@ -51,7 +50,7 @@ Z3CHCInterface::Z3CHCInterface(optional<unsigned> _queryTimeout):
|
|||||||
setSpacerOptions();
|
setSpacerOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Z3CHCInterface::declareVariable(string const& _name, SortPointer const& _sort)
|
void Z3CHCInterface::declareVariable(std::string const& _name, SortPointer const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort, "");
|
smtAssert(_sort, "");
|
||||||
m_z3Interface->declareVariable(_name, _sort);
|
m_z3Interface->declareVariable(_name, _sort);
|
||||||
@ -62,7 +61,7 @@ void Z3CHCInterface::registerRelation(Expression const& _expr)
|
|||||||
m_solver.register_relation(m_z3Interface->functions().at(_expr.name));
|
m_solver.register_relation(m_z3Interface->functions().at(_expr.name));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Z3CHCInterface::addRule(Expression const& _expr, string const& _name)
|
void Z3CHCInterface::addRule(Expression const& _expr, std::string const& _name)
|
||||||
{
|
{
|
||||||
z3::expr rule = m_z3Interface->toZ3Expr(_expr);
|
z3::expr rule = m_z3Interface->toZ3Expr(_expr);
|
||||||
if (m_z3Interface->constants().empty())
|
if (m_z3Interface->constants().empty())
|
||||||
@ -77,7 +76,7 @@ void Z3CHCInterface::addRule(Expression const& _expr, string const& _name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> Z3CHCInterface::query(Expression const& _expr)
|
std::tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> Z3CHCInterface::query(Expression const& _expr)
|
||||||
{
|
{
|
||||||
CheckResult result;
|
CheckResult result;
|
||||||
try
|
try
|
||||||
@ -90,7 +89,7 @@ tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> Z3CHCInterface::que
|
|||||||
result = CheckResult::SATISFIABLE;
|
result = CheckResult::SATISFIABLE;
|
||||||
// z3 version 4.8.8 modified Spacer to also return
|
// z3 version 4.8.8 modified Spacer to also return
|
||||||
// proofs containing nonlinear clauses.
|
// proofs containing nonlinear clauses.
|
||||||
if (m_version >= tuple(4, 8, 8, 0))
|
if (m_version >= std::tuple(4, 8, 8, 0))
|
||||||
{
|
{
|
||||||
auto proof = m_solver.get_answer();
|
auto proof = m_solver.get_answer();
|
||||||
return {result, Expression(true), cexGraph(proof)};
|
return {result, Expression(true), cexGraph(proof)};
|
||||||
@ -113,7 +112,7 @@ tuple<CheckResult, Expression, CHCSolverInterface::CexGraph> Z3CHCInterface::que
|
|||||||
}
|
}
|
||||||
catch (z3::exception const& _err)
|
catch (z3::exception const& _err)
|
||||||
{
|
{
|
||||||
set<string> msgs{
|
std::set<std::string> msgs{
|
||||||
/// Resource limit (rlimit) exhausted.
|
/// Resource limit (rlimit) exhausted.
|
||||||
"max. resource limit exceeded",
|
"max. resource limit exceeded",
|
||||||
/// User given timeout exhausted.
|
/// User given timeout exhausted.
|
||||||
@ -178,13 +177,13 @@ CHCSolverInterface::CexGraph Z3CHCInterface::cexGraph(z3::expr const& _proof)
|
|||||||
|
|
||||||
CexGraph graph;
|
CexGraph graph;
|
||||||
|
|
||||||
stack<z3::expr> proofStack;
|
std::stack<z3::expr> proofStack;
|
||||||
proofStack.push(_proof.arg(0));
|
proofStack.push(_proof.arg(0));
|
||||||
|
|
||||||
auto const& root = proofStack.top();
|
auto const& root = proofStack.top();
|
||||||
graph.nodes.emplace(root.id(), m_z3Interface->fromZ3Expr(fact(root)));
|
graph.nodes.emplace(root.id(), m_z3Interface->fromZ3Expr(fact(root)));
|
||||||
|
|
||||||
set<unsigned> visited;
|
std::set<unsigned> visited;
|
||||||
visited.insert(root.id());
|
visited.insert(root.id());
|
||||||
|
|
||||||
while (!proofStack.empty())
|
while (!proofStack.empty())
|
||||||
@ -227,16 +226,16 @@ z3::expr Z3CHCInterface::fact(z3::expr const& _node)
|
|||||||
return _node.arg(_node.num_args() - 1);
|
return _node.arg(_node.num_args() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
string Z3CHCInterface::name(z3::expr const& _predicate)
|
std::string Z3CHCInterface::name(z3::expr const& _predicate)
|
||||||
{
|
{
|
||||||
smtAssert(_predicate.is_app(), "");
|
smtAssert(_predicate.is_app(), "");
|
||||||
return _predicate.decl().name().str();
|
return _predicate.decl().name().str();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> Z3CHCInterface::arguments(z3::expr const& _predicate)
|
std::vector<std::string> Z3CHCInterface::arguments(z3::expr const& _predicate)
|
||||||
{
|
{
|
||||||
smtAssert(_predicate.is_app(), "");
|
smtAssert(_predicate.is_app(), "");
|
||||||
vector<string> args;
|
std::vector<std::string> args;
|
||||||
for (unsigned i = 0; i < _predicate.num_args(); ++i)
|
for (unsigned i = 0; i < _predicate.num_args(); ++i)
|
||||||
args.emplace_back(_predicate.arg(i).to_string());
|
args.emplace_back(_predicate.arg(i).to_string());
|
||||||
return args;
|
return args;
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <libsmtutil/Z3Loader.h>
|
#include <libsmtutil/Z3Loader.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity::smtutil;
|
using namespace solidity::smtutil;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
|
|
||||||
@ -69,7 +68,7 @@ void Z3Interface::pop()
|
|||||||
m_solver.pop();
|
m_solver.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Z3Interface::declareVariable(string const& _name, SortPointer const& _sort)
|
void Z3Interface::declareVariable(std::string const& _name, SortPointer const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort, "");
|
smtAssert(_sort, "");
|
||||||
if (_sort->kind == Kind::Function)
|
if (_sort->kind == Kind::Function)
|
||||||
@ -80,7 +79,7 @@ void Z3Interface::declareVariable(string const& _name, SortPointer const& _sort)
|
|||||||
m_constants.emplace(_name, m_context.constant(_name.c_str(), z3Sort(*_sort)));
|
m_constants.emplace(_name, m_context.constant(_name.c_str(), z3Sort(*_sort)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Z3Interface::declareFunction(string const& _name, Sort const& _sort)
|
void Z3Interface::declareFunction(std::string const& _name, Sort const& _sort)
|
||||||
{
|
{
|
||||||
smtAssert(_sort.kind == Kind::Function, "");
|
smtAssert(_sort.kind == Kind::Function, "");
|
||||||
FunctionSort fSort = dynamic_cast<FunctionSort const&>(_sort);
|
FunctionSort fSort = dynamic_cast<FunctionSort const&>(_sort);
|
||||||
@ -95,10 +94,10 @@ void Z3Interface::addAssertion(Expression const& _expr)
|
|||||||
m_solver.add(toZ3Expr(_expr));
|
m_solver.add(toZ3Expr(_expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _expressionsToEvaluate)
|
std::pair<CheckResult, std::vector<std::string>> Z3Interface::check(std::vector<Expression> const& _expressionsToEvaluate)
|
||||||
{
|
{
|
||||||
CheckResult result;
|
CheckResult result;
|
||||||
vector<string> values;
|
std::vector<std::string> values;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
switch (m_solver.check())
|
switch (m_solver.check())
|
||||||
@ -123,7 +122,7 @@ pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _
|
|||||||
}
|
}
|
||||||
catch (z3::exception const& _err)
|
catch (z3::exception const& _err)
|
||||||
{
|
{
|
||||||
set<string> msgs{
|
std::set<std::string> msgs{
|
||||||
/// Resource limit (rlimit) exhausted.
|
/// Resource limit (rlimit) exhausted.
|
||||||
"max. resource limit exceeded",
|
"max. resource limit exceeded",
|
||||||
/// User given timeout exhausted.
|
/// User given timeout exhausted.
|
||||||
@ -137,7 +136,7 @@ pair<CheckResult, vector<string>> Z3Interface::check(vector<Expression> const& _
|
|||||||
values.clear();
|
values.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return make_pair(result, values);
|
return std::make_pair(result, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
|
z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
|
||||||
@ -150,7 +149,7 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string const& n = _expr.name;
|
std::string const& n = _expr.name;
|
||||||
if (m_functions.count(n))
|
if (m_functions.count(n))
|
||||||
return m_functions.at(n)(arguments);
|
return m_functions.at(n)(arguments);
|
||||||
else if (m_constants.count(n))
|
else if (m_constants.count(n))
|
||||||
@ -166,7 +165,7 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
|
|||||||
return m_context.bool_val(false);
|
return m_context.bool_val(false);
|
||||||
else if (_expr.sort->kind == Kind::Sort)
|
else if (_expr.sort->kind == Kind::Sort)
|
||||||
{
|
{
|
||||||
auto sortSort = dynamic_pointer_cast<SortSort>(_expr.sort);
|
auto sortSort = std::dynamic_pointer_cast<SortSort>(_expr.sort);
|
||||||
smtAssert(sortSort, "");
|
smtAssert(sortSort, "");
|
||||||
return m_context.constant(n.c_str(), z3Sort(*sortSort->inner));
|
return m_context.constant(n.c_str(), z3Sort(*sortSort->inner));
|
||||||
}
|
}
|
||||||
@ -233,7 +232,7 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
|
|||||||
}
|
}
|
||||||
else if (n == "bv2int")
|
else if (n == "bv2int")
|
||||||
{
|
{
|
||||||
auto intSort = dynamic_pointer_cast<IntSort>(_expr.sort);
|
auto intSort = std::dynamic_pointer_cast<IntSort>(_expr.sort);
|
||||||
smtAssert(intSort, "");
|
smtAssert(intSort, "");
|
||||||
return z3::bv2int(arguments[0], intSort->isSigned);
|
return z3::bv2int(arguments[0], intSort->isSigned);
|
||||||
}
|
}
|
||||||
@ -243,9 +242,9 @@ z3::expr Z3Interface::toZ3Expr(Expression const& _expr)
|
|||||||
return z3::store(arguments[0], arguments[1], arguments[2]);
|
return z3::store(arguments[0], arguments[1], arguments[2]);
|
||||||
else if (n == "const_array")
|
else if (n == "const_array")
|
||||||
{
|
{
|
||||||
shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort);
|
std::shared_ptr<SortSort> sortSort = std::dynamic_pointer_cast<SortSort>(_expr.arguments[0].sort);
|
||||||
smtAssert(sortSort, "");
|
smtAssert(sortSort, "");
|
||||||
auto arraySort = dynamic_pointer_cast<ArraySort>(sortSort->inner);
|
auto arraySort = std::dynamic_pointer_cast<ArraySort>(sortSort->inner);
|
||||||
smtAssert(arraySort && arraySort->domain, "");
|
smtAssert(arraySort && arraySort->domain, "");
|
||||||
return z3::const_array(z3Sort(*arraySort->domain), arguments[1]);
|
return z3::const_array(z3Sort(*arraySort->domain), arguments[1]);
|
||||||
}
|
}
|
||||||
@ -285,7 +284,7 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr)
|
|||||||
|
|
||||||
if (_expr.is_quantifier())
|
if (_expr.is_quantifier())
|
||||||
{
|
{
|
||||||
string quantifierName;
|
std::string quantifierName;
|
||||||
if (_expr.is_exists())
|
if (_expr.is_exists())
|
||||||
quantifierName = "exists";
|
quantifierName = "exists";
|
||||||
else if (_expr.is_forall())
|
else if (_expr.is_forall())
|
||||||
@ -297,7 +296,7 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr)
|
|||||||
return Expression(quantifierName, {fromZ3Expr(_expr.body())}, sort);
|
return Expression(quantifierName, {fromZ3Expr(_expr.body())}, sort);
|
||||||
}
|
}
|
||||||
smtAssert(_expr.is_app(), "");
|
smtAssert(_expr.is_app(), "");
|
||||||
vector<Expression> arguments;
|
std::vector<Expression> arguments;
|
||||||
for (unsigned i = 0; i < _expr.num_args(); ++i)
|
for (unsigned i = 0; i < _expr.num_args(); ++i)
|
||||||
arguments.push_back(fromZ3Expr(_expr.arg(i)));
|
arguments.push_back(fromZ3Expr(_expr.arg(i)));
|
||||||
|
|
||||||
@ -370,12 +369,12 @@ Expression Z3Interface::fromZ3Expr(z3::expr const& _expr)
|
|||||||
return Expression::store(arguments[0], arguments[1], arguments[2]);
|
return Expression::store(arguments[0], arguments[1], arguments[2]);
|
||||||
else if (kind == Z3_OP_CONST_ARRAY)
|
else if (kind == Z3_OP_CONST_ARRAY)
|
||||||
{
|
{
|
||||||
auto sortSort = make_shared<SortSort>(fromZ3Sort(_expr.get_sort()));
|
auto sortSort = std::make_shared<SortSort>(fromZ3Sort(_expr.get_sort()));
|
||||||
return Expression::const_array(Expression(sortSort), arguments[0]);
|
return Expression::const_array(Expression(sortSort), arguments[0]);
|
||||||
}
|
}
|
||||||
else if (kind == Z3_OP_DT_CONSTRUCTOR)
|
else if (kind == Z3_OP_DT_CONSTRUCTOR)
|
||||||
{
|
{
|
||||||
auto sortSort = make_shared<SortSort>(fromZ3Sort(_expr.get_sort()));
|
auto sortSort = std::make_shared<SortSort>(fromZ3Sort(_expr.get_sort()));
|
||||||
return Expression::tuple_constructor(Expression(sortSort), arguments);
|
return Expression::tuple_constructor(Expression(sortSort), arguments);
|
||||||
}
|
}
|
||||||
else if (kind == Z3_OP_DT_ACCESSOR)
|
else if (kind == Z3_OP_DT_ACCESSOR)
|
||||||
@ -412,12 +411,12 @@ z3::sort Z3Interface::z3Sort(Sort const& _sort)
|
|||||||
case Kind::Tuple:
|
case Kind::Tuple:
|
||||||
{
|
{
|
||||||
auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort);
|
auto const& tupleSort = dynamic_cast<TupleSort const&>(_sort);
|
||||||
vector<char const*> cMembers;
|
std::vector<char const*> cMembers;
|
||||||
for (auto const& member: tupleSort.members)
|
for (auto const& member: tupleSort.members)
|
||||||
cMembers.emplace_back(member.c_str());
|
cMembers.emplace_back(member.c_str());
|
||||||
/// Using this instead of the function below because with that one
|
/// Using this instead of the function below because with that one
|
||||||
/// we can't use `&sorts[0]` here.
|
/// we can't use `&sorts[0]` here.
|
||||||
vector<z3::sort> sorts;
|
std::vector<z3::sort> sorts;
|
||||||
for (auto const& sort: tupleSort.components)
|
for (auto const& sort: tupleSort.components)
|
||||||
sorts.push_back(z3Sort(*sort));
|
sorts.push_back(z3Sort(*sort));
|
||||||
z3::func_decl_vector projs(m_context);
|
z3::func_decl_vector projs(m_context);
|
||||||
@ -439,7 +438,7 @@ z3::sort Z3Interface::z3Sort(Sort const& _sort)
|
|||||||
return m_context.int_sort();
|
return m_context.int_sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
z3::sort_vector Z3Interface::z3Sort(vector<SortPointer> const& _sorts)
|
z3::sort_vector Z3Interface::z3Sort(std::vector<SortPointer> const& _sorts)
|
||||||
{
|
{
|
||||||
z3::sort_vector z3Sorts(m_context);
|
z3::sort_vector z3Sorts(m_context);
|
||||||
for (auto const& _sort: _sorts)
|
for (auto const& _sort: _sorts)
|
||||||
@ -454,27 +453,27 @@ SortPointer Z3Interface::fromZ3Sort(z3::sort const& _sort)
|
|||||||
if (_sort.is_int())
|
if (_sort.is_int())
|
||||||
return SortProvider::sintSort;
|
return SortProvider::sintSort;
|
||||||
if (_sort.is_bv())
|
if (_sort.is_bv())
|
||||||
return make_shared<BitVectorSort>(_sort.bv_size());
|
return std::make_shared<BitVectorSort>(_sort.bv_size());
|
||||||
if (_sort.is_array())
|
if (_sort.is_array())
|
||||||
return make_shared<ArraySort>(fromZ3Sort(_sort.array_domain()), fromZ3Sort(_sort.array_range()));
|
return std::make_shared<ArraySort>(fromZ3Sort(_sort.array_domain()), fromZ3Sort(_sort.array_range()));
|
||||||
if (_sort.is_datatype())
|
if (_sort.is_datatype())
|
||||||
{
|
{
|
||||||
auto name = _sort.name().str();
|
auto name = _sort.name().str();
|
||||||
auto constructor = z3::func_decl(m_context, Z3_get_tuple_sort_mk_decl(m_context, _sort));
|
auto constructor = z3::func_decl(m_context, Z3_get_tuple_sort_mk_decl(m_context, _sort));
|
||||||
vector<string> memberNames;
|
std::vector<std::string> memberNames;
|
||||||
vector<SortPointer> memberSorts;
|
std::vector<SortPointer> memberSorts;
|
||||||
for (unsigned i = 0; i < constructor.arity(); ++i)
|
for (unsigned i = 0; i < constructor.arity(); ++i)
|
||||||
{
|
{
|
||||||
auto accessor = z3::func_decl(m_context, Z3_get_tuple_sort_field_decl(m_context, _sort, i));
|
auto accessor = z3::func_decl(m_context, Z3_get_tuple_sort_field_decl(m_context, _sort, i));
|
||||||
memberNames.push_back(accessor.name().str());
|
memberNames.push_back(accessor.name().str());
|
||||||
memberSorts.push_back(fromZ3Sort(accessor.range()));
|
memberSorts.push_back(fromZ3Sort(accessor.range()));
|
||||||
}
|
}
|
||||||
return make_shared<TupleSort>(name, memberNames, memberSorts);
|
return std::make_shared<TupleSort>(name, memberNames, memberSorts);
|
||||||
}
|
}
|
||||||
smtAssert(false, "");
|
smtAssert(false, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<SortPointer> Z3Interface::fromZ3Sort(z3::sort_vector const& _sorts)
|
std::vector<SortPointer> Z3Interface::fromZ3Sort(z3::sort_vector const& _sorts)
|
||||||
{
|
{
|
||||||
return applyMap(_sorts, [this](auto const& sort) { return fromZ3Sort(sort); });
|
return applyMap(_sorts, [this](auto const& sort) { return fromZ3Sort(sort); });
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::smtutil;
|
using namespace solidity::smtutil;
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ void* Z3Loader::loadSymbol(char const* _name) const
|
|||||||
{
|
{
|
||||||
smtAssert(m_handle, "Attempted to use dynamically loaded Z3, even though it is not available.");
|
smtAssert(m_handle, "Attempted to use dynamically loaded Z3, even though it is not available.");
|
||||||
void* sym = dlsym(m_handle, _name);
|
void* sym = dlsym(m_handle, _name);
|
||||||
smtAssert(sym, string("Symbol \"") + _name + "\" not found in libz3.so");
|
smtAssert(sym, std::string("Symbol \"") + _name + "\" not found in libz3.so");
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ bool Z3Loader::available() const
|
|||||||
|
|
||||||
Z3Loader::Z3Loader()
|
Z3Loader::Z3Loader()
|
||||||
{
|
{
|
||||||
string libname{"libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION)};
|
std::string libname{"libz3.so." + std::to_string(Z3_MAJOR_VERSION) + "." + std::to_string(Z3_MINOR_VERSION)};
|
||||||
m_handle = dlmopen(LM_ID_NEWLM, libname.c_str(), RTLD_NOW);
|
m_handle = dlmopen(LM_ID_NEWLM, libname.c_str(), RTLD_NOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
|
|
||||||
#include "license.h"
|
#include "license.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
|
|
||||||
@ -42,21 +41,21 @@ using solidity::frontend::StandardCompiler;
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
// The strings in this list must not be resized after they have been added here (via solidity_alloc()), because
|
// The std::strings in this list must not be resized after they have been added here (via solidity_alloc()), because
|
||||||
// this may potentially change the pointer that was passed to the caller from solidity_alloc().
|
// this may potentially change the pointer that was passed to the caller from solidity_alloc().
|
||||||
static list<string> solidityAllocations;
|
static std::list<std::string> solidityAllocations;
|
||||||
|
|
||||||
/// Find the equivalent to @p _data in the list of allocations of solidity_alloc(),
|
/// Find the equivalent to @p _data in the list of allocations of solidity_alloc(),
|
||||||
/// removes it from the list and returns its value.
|
/// removes it from the list and returns its value.
|
||||||
///
|
///
|
||||||
/// If any invalid argument is being passed, it is considered a programming error
|
/// If any invalid argument is being passed, it is considered a programming error
|
||||||
/// on the caller-side and hence, will call abort() then.
|
/// on the caller-side and hence, will call abort() then.
|
||||||
string takeOverAllocation(char const* _data)
|
std::string takeOverAllocation(char const* _data)
|
||||||
{
|
{
|
||||||
for (auto iter = begin(solidityAllocations); iter != end(solidityAllocations); ++iter)
|
for (auto iter = begin(solidityAllocations); iter != end(solidityAllocations); ++iter)
|
||||||
if (iter->data() == _data)
|
if (iter->data() == _data)
|
||||||
{
|
{
|
||||||
string chunk = std::move(*iter);
|
std::string chunk = std::move(*iter);
|
||||||
solidityAllocations.erase(iter);
|
solidityAllocations.erase(iter);
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
@ -64,11 +63,11 @@ string takeOverAllocation(char const* _data)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resizes a std::string to the proper length based on the occurrence of a zero terminator.
|
/// Resizes a std::std::string to the proper length based on the occurrence of a zero terminator.
|
||||||
void truncateCString(string& _data)
|
void truncateCString(std::string& _data)
|
||||||
{
|
{
|
||||||
size_t pos = _data.find('\0');
|
size_t pos = _data.find('\0');
|
||||||
if (pos != string::npos)
|
if (pos != std::string::npos)
|
||||||
_data.resize(pos);
|
_data.resize(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +76,7 @@ ReadCallback::Callback wrapReadCallback(CStyleReadFileCallback _readCallback, vo
|
|||||||
ReadCallback::Callback readCallback;
|
ReadCallback::Callback readCallback;
|
||||||
if (_readCallback)
|
if (_readCallback)
|
||||||
{
|
{
|
||||||
readCallback = [=](string const& _kind, string const& _data)
|
readCallback = [=](std::string const& _kind, std::string const& _data)
|
||||||
{
|
{
|
||||||
char* contents_c = nullptr;
|
char* contents_c = nullptr;
|
||||||
char* error_c = nullptr;
|
char* error_c = nullptr;
|
||||||
@ -106,7 +105,7 @@ ReadCallback::Callback wrapReadCallback(CStyleReadFileCallback _readCallback, vo
|
|||||||
return readCallback;
|
return readCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
string compile(string _input, CStyleReadFileCallback _readCallback, void* _readContext)
|
std::string compile(std::string _input, CStyleReadFileCallback _readCallback, void* _readContext)
|
||||||
{
|
{
|
||||||
StandardCompiler compiler(wrapReadCallback(_readCallback, _readContext));
|
StandardCompiler compiler(wrapReadCallback(_readCallback, _readContext));
|
||||||
return compiler.compile(std::move(_input));
|
return compiler.compile(std::move(_input));
|
||||||
@ -118,7 +117,7 @@ extern "C"
|
|||||||
{
|
{
|
||||||
extern char const* solidity_license() noexcept
|
extern char const* solidity_license() noexcept
|
||||||
{
|
{
|
||||||
static string fullLicenseText = otherLicenses + licenseText;
|
static std::string fullLicenseText = otherLicenses + licenseText;
|
||||||
return fullLicenseText.c_str();
|
return fullLicenseText.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,8 @@ EXCLUDE_FILES_JOINED=${EXCLUDE_FILES_JOINED%??}
|
|||||||
NAMESPACE_STD_FREE_FILES=(
|
NAMESPACE_STD_FREE_FILES=(
|
||||||
libevmasm/*
|
libevmasm/*
|
||||||
liblangutil/*
|
liblangutil/*
|
||||||
|
libsmtutil/*
|
||||||
|
libsolc/*
|
||||||
)
|
)
|
||||||
|
|
||||||
(
|
(
|
||||||
|
Loading…
Reference in New Issue
Block a user