[SMTChecker] Support to bitwise

This commit is contained in:
Leonardo Alt
2020-05-27 20:59:00 +02:00
parent 9f407fe0e7
commit 9e9f0c52e1
16 changed files with 277 additions and 17 deletions
+3 -3
View File
@@ -701,7 +701,7 @@ vector<smtutil::SortPointer> CHC::stateSorts(ContractDefinition const& _contract
smtutil::SortPointer CHC::constructorSort()
{
return make_shared<smtutil::FunctionSort>(
vector<smtutil::SortPointer>{smtutil::SortProvider::intSort} + m_stateSorts,
vector<smtutil::SortPointer>{smtutil::SortProvider::uintSort} + m_stateSorts,
smtutil::SortProvider::boolSort
);
}
@@ -747,7 +747,7 @@ smtutil::SortPointer CHC::sort(FunctionDefinition const& _function)
auto inputSorts = applyMap(_function.parameters(), smtSort);
auto outputSorts = applyMap(_function.returnParameters(), smtSort);
return make_shared<smtutil::FunctionSort>(
vector<smtutil::SortPointer>{smtutil::SortProvider::intSort} + m_stateSorts + inputSorts + m_stateSorts + inputSorts + outputSorts,
vector<smtutil::SortPointer>{smtutil::SortProvider::uintSort} + m_stateSorts + inputSorts + m_stateSorts + inputSorts + outputSorts,
smtutil::SortProvider::boolSort
);
}
@@ -776,7 +776,7 @@ smtutil::SortPointer CHC::summarySort(FunctionDefinition const& _function, Contr
auto inputSorts = applyMap(_function.parameters(), smtSort);
auto outputSorts = applyMap(_function.returnParameters(), smtSort);
return make_shared<smtutil::FunctionSort>(
vector<smtutil::SortPointer>{smtutil::SortProvider::intSort} + sorts + inputSorts + sorts + outputSorts,
vector<smtutil::SortPointer>{smtutil::SortProvider::uintSort} + sorts + inputSorts + sorts + outputSorts,
smtutil::SortProvider::boolSort
);
}
+39
View File
@@ -574,6 +574,8 @@ void SMTEncoder::endVisit(BinaryOperation const& _op)
arithmeticOperation(_op);
else if (TokenTraits::isCompareOp(_op.getOperator()))
compareOperation(_op);
else if (TokenTraits::isBitOp(_op.getOperator()))
bitwiseOperation(_op);
else
m_errorReporter.warning(
3876_error,
@@ -1346,6 +1348,43 @@ void SMTEncoder::booleanOperation(BinaryOperation const& _op)
);
}
void SMTEncoder::bitwiseOperation(BinaryOperation const& _op)
{
solAssert(TokenTraits::isBitOp(_op.getOperator()), "");
auto commonType = _op.annotation().commonType;
solAssert(commonType, "");
unsigned bvSize = 256;
bool isSigned = false;
if (auto const* intType = dynamic_cast<IntegerType const*>(commonType))
{
bvSize = intType->numBits();
isSigned = intType->isSigned();
}
else if (auto const* fixedType = dynamic_cast<FixedPointType const*>(commonType))
{
bvSize = fixedType->numBits();
isSigned = fixedType->isSigned();
}
auto bvLeft = smtutil::Expression::int2bv(expr(_op.leftExpression()), bvSize);
auto bvRight = smtutil::Expression::int2bv(expr(_op.rightExpression()), bvSize);
optional<smtutil::Expression> result;
if (_op.getOperator() == Token::BitAnd)
result = bvLeft & bvRight;
// TODO implement the other operators
else
m_errorReporter.warning(
1093_error,
_op.location(),
"Assertion checker does not yet implement this bitwise operator."
);
if (result)
defineExpr(_op, smtutil::Expression::bv2int(*result, isSigned));
}
smtutil::Expression SMTEncoder::division(smtutil::Expression _left, smtutil::Expression _right, IntegerType const& _type)
{
// Signed division in SMTLIB2 rounds differently for negative division.
+1
View File
@@ -108,6 +108,7 @@ protected:
);
void compareOperation(BinaryOperation const& _op);
void booleanOperation(BinaryOperation const& _op);
void bitwiseOperation(BinaryOperation const& _op);
void initContract(ContractDefinition const& _contract);
void initFunction(FunctionDefinition const& _function);
+1 -1
View File
@@ -63,7 +63,7 @@ private:
/// Symbolic balances.
SymbolicArrayVariable m_balances{
std::make_shared<smtutil::ArraySort>(smtutil::SortProvider::intSort, smtutil::SortProvider::intSort),
std::make_shared<smtutil::ArraySort>(smtutil::SortProvider::uintSort, smtutil::SortProvider::uintSort),
"balances",
m_context
};
+12 -8
View File
@@ -34,7 +34,11 @@ SortPointer smtSort(frontend::Type const& _type)
switch (smtKind(_type.category()))
{
case Kind::Int:
return SortProvider::intSort;
if (auto const* intType = dynamic_cast<IntegerType const*>(&_type))
return SortProvider::intSort(intType->isSigned());
if (auto const* fixedType = dynamic_cast<FixedPointType const*>(&_type))
return SortProvider::intSort(fixedType->isSigned());
return SortProvider::uintSort;
case Kind::Bool:
return SortProvider::boolSort;
case Kind::Function:
@@ -50,7 +54,7 @@ SortPointer smtSort(frontend::Type const& _type)
returnSort = SortProvider::boolSort;
else if (returnTypes.size() > 1)
// Abstract sort.
returnSort = SortProvider::intSort;
returnSort = SortProvider::uintSort;
else
returnSort = smtSort(*returnTypes.front());
return make_shared<FunctionSort>(parameterSorts, returnSort);
@@ -68,7 +72,7 @@ SortPointer smtSort(frontend::Type const& _type)
{
auto stringLitType = dynamic_cast<frontend::StringLiteralType const*>(&_type);
solAssert(stringLitType, "");
array = make_shared<ArraySort>(SortProvider::intSort, SortProvider::intSort);
array = make_shared<ArraySort>(SortProvider::uintSort, SortProvider::uintSort);
}
else
{
@@ -81,7 +85,7 @@ SortPointer smtSort(frontend::Type const& _type)
solAssert(false, "");
solAssert(arrayType, "");
array = make_shared<ArraySort>(SortProvider::intSort, smtSortAbstractFunction(*arrayType->baseType()));
array = make_shared<ArraySort>(SortProvider::uintSort, smtSortAbstractFunction(*arrayType->baseType()));
}
string tupleName;
@@ -98,7 +102,7 @@ SortPointer smtSort(frontend::Type const& _type)
return make_shared<TupleSort>(
tupleName,
vector<string>{tupleName + "_accessor_array", tupleName + "_accessor_length"},
vector<SortPointer>{array, SortProvider::intSort}
vector<SortPointer>{array, SortProvider::uintSort}
);
}
case Kind::Tuple:
@@ -118,7 +122,7 @@ SortPointer smtSort(frontend::Type const& _type)
}
default:
// Abstract case.
return SortProvider::intSort;
return SortProvider::uintSort;
}
}
@@ -133,7 +137,7 @@ vector<SortPointer> smtSort(vector<frontend::TypePointer> const& _types)
SortPointer smtSortAbstractFunction(frontend::Type const& _type)
{
if (isFunction(_type.category()))
return SortProvider::intSort;
return SortProvider::uintSort;
return smtSort(_type);
}
@@ -144,7 +148,7 @@ vector<SortPointer> smtSortAbstractFunction(vector<frontend::TypePointer> const&
if (type)
sorts.push_back(smtSortAbstractFunction(*type));
else
sorts.push_back(SortProvider::intSort);
sorts.push_back(SortProvider::uintSort);
return sorts;
}
+1 -1
View File
@@ -286,7 +286,7 @@ SymbolicArrayVariable::SymbolicArrayVariable(
std::make_shared<TupleSort>(
"array_length_pair",
std::vector<std::string>{"array", "length"},
std::vector<SortPointer>{m_sort, SortProvider::intSort}
std::vector<SortPointer>{m_sort, SortProvider::uintSort}
),
m_uniqueName + "_array_length_pair",
m_context