Verification: Added IntRange::isLessThan and IntRange::isGreaterThan

This commit is contained in:
Daniel Marjamäki 2019-12-26 15:39:08 +01:00
parent 678560bf0d
commit 8c652afd6e
2 changed files with 60 additions and 0 deletions

View File

@ -707,6 +707,64 @@ bool ExprEngine::IntRange::isEqual(DataBase *dataBase, int value) const
#endif #endif
} }
bool ExprEngine::IntRange::isGreaterThan(DataBase *dataBase, int value) const
{
if (value < minValue || value > maxValue)
return false;
const Data *data = dynamic_cast<Data *>(dataBase);
if (data->constraints.empty())
return true;
#ifdef USE_Z3
// Check the value against the constraints
ExprData exprData;
z3::solver solver(exprData.context);
try {
z3::expr e = exprData.context.int_const(name.c_str());
exprData.valueExpr.emplace(name, e);
for (auto constraint : dynamic_cast<const Data *>(dataBase)->constraints)
solver.add(exprData.getConstraintExpr(constraint));
solver.add(e > value);
return solver.check() == z3::sat;
} catch (const z3::exception &exception) {
std::cerr << "z3: " << exception << std::endl;
return true; // Safe option is to return true
}
#else
// The value may or may not be in range
return false;
#endif
}
bool ExprEngine::IntRange::isLessThan(DataBase *dataBase, int value) const
{
if (value < minValue || value > maxValue)
return false;
const Data *data = dynamic_cast<Data *>(dataBase);
if (data->constraints.empty())
return true;
#ifdef USE_Z3
// Check the value against the constraints
ExprData exprData;
z3::solver solver(exprData.context);
try {
z3::expr e = exprData.context.int_const(name.c_str());
exprData.valueExpr.emplace(name, e);
for (auto constraint : dynamic_cast<const Data *>(dataBase)->constraints)
solver.add(exprData.getConstraintExpr(constraint));
solver.add(e < value);
return solver.check() == z3::sat;
} catch (const z3::exception &exception) {
std::cerr << "z3: " << exception << std::endl;
return true; // Safe option is to return true
}
#else
// The value may or may not be in range
return false;
#endif
}
bool ExprEngine::BinOpResult::isEqual(ExprEngine::DataBase *dataBase, int value) const bool ExprEngine::BinOpResult::isEqual(ExprEngine::DataBase *dataBase, int value) const
{ {
#ifdef USE_Z3 #ifdef USE_Z3

View File

@ -129,6 +129,8 @@ namespace ExprEngine {
return str(minValue) + ":" + str(maxValue); return str(minValue) + ":" + str(maxValue);
} }
bool isEqual(DataBase *dataBase, int value) const override; bool isEqual(DataBase *dataBase, int value) const override;
bool isGreaterThan(DataBase *dataBase, int value) const override;
bool isLessThan(DataBase *dataBase, int value) const override;
int128_t minValue; int128_t minValue;
int128_t maxValue; int128_t maxValue;