Check early if solvers are available.

This commit is contained in:
Leo Alt 2022-05-10 19:04:37 +02:00
parent 1d7b4704bb
commit 75d08ea924
4 changed files with 48 additions and 53 deletions

View File

@ -63,15 +63,14 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
{ {
if (m_interface->solvers() == 0) if (m_interface->solvers() == 0)
{ {
if (!m_noSolverWarning) m_errorReporter.warning(
{ 7710_error,
m_noSolverWarning = true; SourceLocation(),
m_errorReporter.warning( "BMC analysis was not possible since no SMT solver was found and enabled."
7710_error, #ifdef HAVE_Z3_DLOPEN
SourceLocation(), " Install libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " to enable Z3."
"BMC analysis was not possible since no SMT solver was found and enabled." #endif
); );
}
return; return;
} }
@ -108,21 +107,15 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
m_interface->solvers() == 1 && m_interface->solvers() == 1 &&
m_settings.solvers.smtlib2 m_settings.solvers.smtlib2
) )
{ m_errorReporter.warning(
if (!m_noSolverWarning) 8084_error,
{ SourceLocation(),
m_noSolverWarning = true; "BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available."
m_errorReporter.warning( " None of the installed solvers was enabled."
8084_error,
SourceLocation(),
"BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available."
" None of the installed solvers was enabled."
#ifdef HAVE_Z3_DLOPEN #ifdef HAVE_Z3_DLOPEN
" Install libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " to enable Z3." " Install libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " to enable Z3."
#endif #endif
); );
}
}
} }
bool BMC::shouldInlineFunctionCall( bool BMC::shouldInlineFunctionCall(

View File

@ -60,21 +60,15 @@ using namespace solidity::frontend::smt;
CHC::CHC( CHC::CHC(
EncodingContext& _context, EncodingContext& _context,
UniqueErrorReporter& _errorReporter, UniqueErrorReporter& _errorReporter,
[[maybe_unused]] map<util::h256, string> const& _smtlib2Responses, map<util::h256, string> const& _smtlib2Responses,
[[maybe_unused]] ReadCallback::Callback const& _smtCallback, ReadCallback::Callback const& _smtCallback,
ModelCheckerSettings const& _settings, ModelCheckerSettings const& _settings,
CharStreamProvider const& _charStreamProvider CharStreamProvider const& _charStreamProvider
): ):
SMTEncoder(_context, _settings, _errorReporter, _charStreamProvider) SMTEncoder(_context, _settings, _errorReporter, _charStreamProvider),
m_smtlib2Responses(_smtlib2Responses),
m_smtCallback(_smtCallback)
{ {
bool usesZ3 = m_settings.solvers.z3;
#ifdef HAVE_Z3
usesZ3 = usesZ3 && Z3Interface::available();
#else
usesZ3 = false;
#endif
if (!usesZ3 && m_settings.solvers.smtlib2)
m_interface = make_unique<CHCSmtLib2Interface>(_smtlib2Responses, _smtCallback, m_settings.timeout);
} }
void CHC::analyze(SourceUnit const& _source) void CHC::analyze(SourceUnit const& _source)
@ -82,17 +76,26 @@ void CHC::analyze(SourceUnit const& _source)
if (!shouldAnalyze(_source)) if (!shouldAnalyze(_source))
return; return;
if (!m_settings.solvers.z3 && !m_settings.solvers.smtlib2) bool usesZ3 = m_settings.solvers.z3;
#ifdef HAVE_Z3_DLOPEN
if (m_settings.solvers.z3 && !Z3Interface::available())
{ {
if (!m_noSolverWarning) usesZ3 = false;
{ m_errorReporter.warning(
m_noSolverWarning = true; 8158_error,
m_errorReporter.warning( SourceLocation(),
7649_error, "z3 was selected as a Horn solver for CHC analysis but libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " was not found."
SourceLocation(), );
"CHC analysis was not possible since no Horn solver was enabled." }
); #endif
}
if (!usesZ3 && !m_settings.solvers.smtlib2)
{
m_errorReporter.warning(
7649_error,
SourceLocation(),
"CHC analysis was not possible since no Horn solver was found and enabled."
);
return; return;
} }
@ -115,20 +118,13 @@ void CHC::analyze(SourceUnit const& _source)
// actually given and the queries were solved. // actually given and the queries were solved.
if (auto const* smtLibInterface = dynamic_cast<CHCSmtLib2Interface const*>(m_interface.get())) if (auto const* smtLibInterface = dynamic_cast<CHCSmtLib2Interface const*>(m_interface.get()))
ranSolver = smtLibInterface->unhandledQueries().empty(); ranSolver = smtLibInterface->unhandledQueries().empty();
if (!ranSolver && !m_noSolverWarning) if (!ranSolver)
{
m_noSolverWarning = true;
m_errorReporter.warning( m_errorReporter.warning(
3996_error, 3996_error,
SourceLocation(), SourceLocation(),
#ifdef HAVE_Z3_DLOPEN
"CHC analysis was not possible since libz3.so." + to_string(Z3_MAJOR_VERSION) + "." + to_string(Z3_MINOR_VERSION) + " was not found."
#else
"CHC analysis was not possible. No Horn solver was available." "CHC analysis was not possible. No Horn solver was available."
" None of the installed solvers was enabled." " None of the installed solvers was enabled."
#endif
); );
}
} }
vector<string> CHC::unhandledQueries() const vector<string> CHC::unhandledQueries() const
@ -1012,6 +1008,11 @@ void CHC::resetSourceAnalysis()
#endif #endif
if (!usesZ3) if (!usesZ3)
{ {
solAssert(m_settings.solvers.smtlib2);
if (!m_interface)
m_interface = make_unique<CHCSmtLib2Interface>(m_smtlib2Responses, m_smtCallback, m_settings.timeout);
auto smtlib2Interface = dynamic_cast<CHCSmtLib2Interface*>(m_interface.get()); auto smtlib2Interface = dynamic_cast<CHCSmtLib2Interface*>(m_interface.get());
solAssert(smtlib2Interface, ""); solAssert(smtlib2Interface, "");
smtlib2Interface->reset(); smtlib2Interface->reset();

View File

@ -421,6 +421,9 @@ private:
/// CHC solver. /// CHC solver.
std::unique_ptr<smtutil::CHCSolverInterface> m_interface; std::unique_ptr<smtutil::CHCSolverInterface> m_interface;
std::map<util::h256, std::string> const& m_smtlib2Responses;
ReadCallback::Callback const& m_smtCallback;
}; };
} }

View File

@ -426,8 +426,6 @@ protected:
smt::VariableUsage m_variableUsage; smt::VariableUsage m_variableUsage;
bool m_arrayAssignmentHappened = false; bool m_arrayAssignmentHappened = false;
// True if the "No SMT solver available" warning was already created.
bool m_noSolverWarning = false;
/// Stores the instances of an Uninterpreted Function applied to arguments. /// Stores the instances of an Uninterpreted Function applied to arguments.
/// These may be direct application of UFs or Array index access. /// These may be direct application of UFs or Array index access.