mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
group unsupported warnings
This commit is contained in:
parent
0aa85153e5
commit
aacbe72079
@ -5,6 +5,7 @@ Language Features:
|
|||||||
|
|
||||||
Compiler Features:
|
Compiler Features:
|
||||||
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of the analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
|
* SMTChecker: Properties that are proved safe are now reported explicitly at the end of the analysis. By default, only the number of safe properties is shown. The CLI option ``--model-checker-show-proved-safe`` and the JSON option ``settings.modelChecker.showProvedSafe`` can be enabled to show the full list of safe properties.
|
||||||
|
* SMTChecker: Group all messages about unsupported language features in a single warning. The CLI option ``--model-checker-show-unsupported`` and the JSON option ``settings.modelChecker.showUnsupported`` can be enabled to show the full list.
|
||||||
|
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
@ -499,6 +499,23 @@ how many unproved targets there are. If the user wishes to see all the specific
|
|||||||
unproved targets, the CLI option ``--model-checker-show-unproved`` and
|
unproved targets, the CLI option ``--model-checker-show-unproved`` and
|
||||||
the JSON option ``settings.modelChecker.showUnproved = true`` can be used.
|
the JSON option ``settings.modelChecker.showUnproved = true`` can be used.
|
||||||
|
|
||||||
|
Unsupported Language Features
|
||||||
|
=============================
|
||||||
|
|
||||||
|
Certain Solidity language features are not completely supported by the SMT
|
||||||
|
encoding that the SMTChecker applies, for example assembly blocks.
|
||||||
|
The unsupported construct is abstracted via overapproximation to preserve
|
||||||
|
soundness, meaning any properties reported safe are safe even though this
|
||||||
|
feature is unsupported.
|
||||||
|
However such abstraction may cause false positives when the target properties
|
||||||
|
depend on the precise behavior of the unsupported feature.
|
||||||
|
If the encoder encounters such cases it will by default report a generic warning
|
||||||
|
stating how many unsupported features it has seen.
|
||||||
|
If the user wishes to see all the specific unsupported features, the CLI option
|
||||||
|
``--model-checker-show-unsupported`` and the JSON option
|
||||||
|
``settings.modelChecker.showUnsupported = true`` can be used, where their default
|
||||||
|
value is ``false``.
|
||||||
|
|
||||||
Verified Contracts
|
Verified Contracts
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
@ -443,6 +443,8 @@ Input Description
|
|||||||
"showProved": true,
|
"showProved": true,
|
||||||
// Choose whether to output all unproved targets. The default is `false`.
|
// Choose whether to output all unproved targets. The default is `false`.
|
||||||
"showUnproved": true,
|
"showUnproved": true,
|
||||||
|
// Choose whether to output all unsupported language features. The default is `false`.
|
||||||
|
"showUnsupported": true,
|
||||||
// Choose which solvers should be used, if available.
|
// Choose which solvers should be used, if available.
|
||||||
// See the Formal Verification section for the solvers description.
|
// See the Formal Verification section for the solvers description.
|
||||||
"solvers": ["cvc4", "smtlib2", "z3"],
|
"solvers": ["cvc4", "smtlib2", "z3"],
|
||||||
|
@ -33,6 +33,11 @@ class UniqueErrorReporter
|
|||||||
public:
|
public:
|
||||||
UniqueErrorReporter(): m_errorReporter(m_uniqueErrors) {}
|
UniqueErrorReporter(): m_errorReporter(m_uniqueErrors) {}
|
||||||
|
|
||||||
|
void append(UniqueErrorReporter const& _other)
|
||||||
|
{
|
||||||
|
m_errorReporter.append(_other.m_errorReporter.errors());
|
||||||
|
}
|
||||||
|
|
||||||
void warning(ErrorId _error, SourceLocation const& _location, std::string const& _description)
|
void warning(ErrorId _error, SourceLocation const& _location, std::string const& _description)
|
||||||
{
|
{
|
||||||
if (!seen(_error, _location, _description))
|
if (!seen(_error, _location, _description))
|
||||||
|
@ -39,12 +39,13 @@ using namespace solidity::frontend;
|
|||||||
BMC::BMC(
|
BMC::BMC(
|
||||||
smt::EncodingContext& _context,
|
smt::EncodingContext& _context,
|
||||||
UniqueErrorReporter& _errorReporter,
|
UniqueErrorReporter& _errorReporter,
|
||||||
|
UniqueErrorReporter& _unsupportedErrorReporter,
|
||||||
map<h256, string> const& _smtlib2Responses,
|
map<h256, string> const& _smtlib2Responses,
|
||||||
ReadCallback::Callback const& _smtCallback,
|
ReadCallback::Callback const& _smtCallback,
|
||||||
ModelCheckerSettings _settings,
|
ModelCheckerSettings _settings,
|
||||||
CharStreamProvider const& _charStreamProvider
|
CharStreamProvider const& _charStreamProvider
|
||||||
):
|
):
|
||||||
SMTEncoder(_context, _settings, _errorReporter, _charStreamProvider),
|
SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider),
|
||||||
m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _settings.solvers, _settings.timeout))
|
m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _settings.solvers, _settings.timeout))
|
||||||
{
|
{
|
||||||
#if defined (HAVE_Z3) || defined (HAVE_CVC4)
|
#if defined (HAVE_Z3) || defined (HAVE_CVC4)
|
||||||
@ -593,7 +594,7 @@ void BMC::internalOrExternalFunctionCall(FunctionCall const& _funCall)
|
|||||||
// The processing happens in SMT Encoder, but we need to prevent the resetting of the state variables.
|
// The processing happens in SMT Encoder, but we need to prevent the resetting of the state variables.
|
||||||
}
|
}
|
||||||
else if (funType.kind() == FunctionType::Kind::Internal)
|
else if (funType.kind() == FunctionType::Kind::Internal)
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
5729_error,
|
5729_error,
|
||||||
_funCall.location(),
|
_funCall.location(),
|
||||||
"BMC does not yet implement this type of function call."
|
"BMC does not yet implement this type of function call."
|
||||||
|
@ -60,6 +60,7 @@ public:
|
|||||||
BMC(
|
BMC(
|
||||||
smt::EncodingContext& _context,
|
smt::EncodingContext& _context,
|
||||||
langutil::UniqueErrorReporter& _errorReporter,
|
langutil::UniqueErrorReporter& _errorReporter,
|
||||||
|
langutil::UniqueErrorReporter& _unsupportedErrorReporter,
|
||||||
std::map<h256, std::string> const& _smtlib2Responses,
|
std::map<h256, std::string> const& _smtlib2Responses,
|
||||||
ReadCallback::Callback const& _smtCallback,
|
ReadCallback::Callback const& _smtCallback,
|
||||||
ModelCheckerSettings _settings,
|
ModelCheckerSettings _settings,
|
||||||
|
@ -62,12 +62,13 @@ using namespace solidity::frontend::smt;
|
|||||||
CHC::CHC(
|
CHC::CHC(
|
||||||
EncodingContext& _context,
|
EncodingContext& _context,
|
||||||
UniqueErrorReporter& _errorReporter,
|
UniqueErrorReporter& _errorReporter,
|
||||||
|
UniqueErrorReporter& _unsupportedErrorReporter,
|
||||||
map<util::h256, string> const& _smtlib2Responses,
|
map<util::h256, string> const& _smtlib2Responses,
|
||||||
ReadCallback::Callback const& _smtCallback,
|
ReadCallback::Callback const& _smtCallback,
|
||||||
ModelCheckerSettings _settings,
|
ModelCheckerSettings _settings,
|
||||||
CharStreamProvider const& _charStreamProvider
|
CharStreamProvider const& _charStreamProvider
|
||||||
):
|
):
|
||||||
SMTEncoder(_context, _settings, _errorReporter, _charStreamProvider),
|
SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider),
|
||||||
m_smtlib2Responses(_smtlib2Responses),
|
m_smtlib2Responses(_smtlib2Responses),
|
||||||
m_smtCallback(_smtCallback)
|
m_smtCallback(_smtCallback)
|
||||||
{
|
{
|
||||||
|
@ -57,6 +57,7 @@ public:
|
|||||||
CHC(
|
CHC(
|
||||||
smt::EncodingContext& _context,
|
smt::EncodingContext& _context,
|
||||||
langutil::UniqueErrorReporter& _errorReporter,
|
langutil::UniqueErrorReporter& _errorReporter,
|
||||||
|
langutil::UniqueErrorReporter& _unsupportedErrorReporter,
|
||||||
std::map<util::h256, std::string> const& _smtlib2Responses,
|
std::map<util::h256, std::string> const& _smtlib2Responses,
|
||||||
ReadCallback::Callback const& _smtCallback,
|
ReadCallback::Callback const& _smtCallback,
|
||||||
ModelCheckerSettings _settings,
|
ModelCheckerSettings _settings,
|
||||||
|
@ -48,8 +48,8 @@ ModelChecker::ModelChecker(
|
|||||||
m_errorReporter(_errorReporter),
|
m_errorReporter(_errorReporter),
|
||||||
m_settings(std::move(_settings)),
|
m_settings(std::move(_settings)),
|
||||||
m_context(),
|
m_context(),
|
||||||
m_bmc(m_context, m_uniqueErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider),
|
m_bmc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider),
|
||||||
m_chc(m_context, m_uniqueErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider)
|
m_chc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,6 +137,21 @@ void ModelChecker::analyze(SourceUnit const& _source)
|
|||||||
if (m_settings.engine.bmc)
|
if (m_settings.engine.bmc)
|
||||||
m_bmc.analyze(_source, solvedTargets);
|
m_bmc.analyze(_source, solvedTargets);
|
||||||
|
|
||||||
|
if (m_settings.showUnsupported)
|
||||||
|
{
|
||||||
|
m_errorReporter.append(m_unsupportedErrorReporter.errors());
|
||||||
|
m_unsupportedErrorReporter.clear();
|
||||||
|
}
|
||||||
|
else if (!m_unsupportedErrorReporter.errors().empty())
|
||||||
|
m_errorReporter.warning(
|
||||||
|
5724_error,
|
||||||
|
{},
|
||||||
|
"SMTChecker: " +
|
||||||
|
to_string(m_unsupportedErrorReporter.errors().size()) +
|
||||||
|
" unsupported language feature(s)."
|
||||||
|
" Enable the model checker option \"show unsupported\" to see all of them."
|
||||||
|
);
|
||||||
|
|
||||||
m_errorReporter.append(m_uniqueErrorReporter.errors());
|
m_errorReporter.append(m_uniqueErrorReporter.errors());
|
||||||
m_uniqueErrorReporter.clear();
|
m_uniqueErrorReporter.clear();
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,12 @@ private:
|
|||||||
/// to m_errorReporter at the end of the analysis.
|
/// to m_errorReporter at the end of the analysis.
|
||||||
langutil::UniqueErrorReporter m_uniqueErrorReporter;
|
langutil::UniqueErrorReporter m_uniqueErrorReporter;
|
||||||
|
|
||||||
|
/// Used by SMTEncoder, BMC and CHC to accumulate unsupported
|
||||||
|
/// warnings and avoid duplicates.
|
||||||
|
/// This is local to ModelChecker, so needs to be appended
|
||||||
|
/// to m_errorReporter at the end of the analysis.
|
||||||
|
langutil::UniqueErrorReporter m_unsupportedErrorReporter;
|
||||||
|
|
||||||
ModelCheckerSettings m_settings;
|
ModelCheckerSettings m_settings;
|
||||||
|
|
||||||
/// Stores the context of the encoding.
|
/// Stores the context of the encoding.
|
||||||
|
@ -170,6 +170,7 @@ struct ModelCheckerSettings
|
|||||||
ModelCheckerInvariants invariants = ModelCheckerInvariants::Default();
|
ModelCheckerInvariants invariants = ModelCheckerInvariants::Default();
|
||||||
bool showProvedSafe = false;
|
bool showProvedSafe = false;
|
||||||
bool showUnproved = false;
|
bool showUnproved = false;
|
||||||
|
bool showUnsupported = false;
|
||||||
smtutil::SMTSolverChoice solvers = smtutil::SMTSolverChoice::Z3();
|
smtutil::SMTSolverChoice solvers = smtutil::SMTSolverChoice::Z3();
|
||||||
ModelCheckerTargets targets = ModelCheckerTargets::Default();
|
ModelCheckerTargets targets = ModelCheckerTargets::Default();
|
||||||
std::optional<unsigned> timeout;
|
std::optional<unsigned> timeout;
|
||||||
@ -185,6 +186,7 @@ struct ModelCheckerSettings
|
|||||||
invariants == _other.invariants &&
|
invariants == _other.invariants &&
|
||||||
showProvedSafe == _other.showProvedSafe &&
|
showProvedSafe == _other.showProvedSafe &&
|
||||||
showUnproved == _other.showUnproved &&
|
showUnproved == _other.showUnproved &&
|
||||||
|
showUnsupported == _other.showUnsupported &&
|
||||||
solvers == _other.solvers &&
|
solvers == _other.solvers &&
|
||||||
targets == _other.targets &&
|
targets == _other.targets &&
|
||||||
timeout == _other.timeout;
|
timeout == _other.timeout;
|
||||||
|
@ -49,9 +49,11 @@ SMTEncoder::SMTEncoder(
|
|||||||
smt::EncodingContext& _context,
|
smt::EncodingContext& _context,
|
||||||
ModelCheckerSettings _settings,
|
ModelCheckerSettings _settings,
|
||||||
UniqueErrorReporter& _errorReporter,
|
UniqueErrorReporter& _errorReporter,
|
||||||
|
UniqueErrorReporter& _unsupportedErrorReporter,
|
||||||
langutil::CharStreamProvider const& _charStreamProvider
|
langutil::CharStreamProvider const& _charStreamProvider
|
||||||
):
|
):
|
||||||
m_errorReporter(_errorReporter),
|
m_errorReporter(_errorReporter),
|
||||||
|
m_unsupportedErrors(_unsupportedErrorReporter),
|
||||||
m_context(_context),
|
m_context(_context),
|
||||||
m_settings(std::move(_settings)),
|
m_settings(std::move(_settings)),
|
||||||
m_charStreamProvider(_charStreamProvider)
|
m_charStreamProvider(_charStreamProvider)
|
||||||
@ -339,7 +341,7 @@ bool SMTEncoder::visit(InlineAssembly const& _inlineAsm)
|
|||||||
m_context.resetVariable(*var);
|
m_context.resetVariable(*var);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
7737_error,
|
7737_error,
|
||||||
_inlineAsm.location(),
|
_inlineAsm.location(),
|
||||||
"Inline assembly may cause SMTChecker to produce spurious warnings (false positives)."
|
"Inline assembly may cause SMTChecker to produce spurious warnings (false positives)."
|
||||||
@ -458,7 +460,7 @@ void SMTEncoder::endVisit(UnaryOperation const& _op)
|
|||||||
if (*_op.annotation().userDefinedFunction)
|
if (*_op.annotation().userDefinedFunction)
|
||||||
{
|
{
|
||||||
// TODO: Implement user-defined operators properly.
|
// TODO: Implement user-defined operators properly.
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
6156_error,
|
6156_error,
|
||||||
_op.location(),
|
_op.location(),
|
||||||
"User-defined operators are not yet supported by SMTChecker. "s +
|
"User-defined operators are not yet supported by SMTChecker. "s +
|
||||||
@ -560,7 +562,7 @@ void SMTEncoder::endVisit(BinaryOperation const& _op)
|
|||||||
if (*_op.annotation().userDefinedFunction)
|
if (*_op.annotation().userDefinedFunction)
|
||||||
{
|
{
|
||||||
// TODO: Implement user-defined operators properly.
|
// TODO: Implement user-defined operators properly.
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
6756_error,
|
6756_error,
|
||||||
_op.location(),
|
_op.location(),
|
||||||
"User-defined operators are not yet supported by SMTChecker. "s +
|
"User-defined operators are not yet supported by SMTChecker. "s +
|
||||||
@ -726,7 +728,7 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall)
|
|||||||
return;
|
return;
|
||||||
case FunctionType::Kind::Creation:
|
case FunctionType::Kind::Creation:
|
||||||
if (!m_settings.engine.chc || !m_settings.externalCalls.isTrusted())
|
if (!m_settings.engine.chc || !m_settings.externalCalls.isTrusted())
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
8729_error,
|
8729_error,
|
||||||
_funCall.location(),
|
_funCall.location(),
|
||||||
"Contract deployment is only supported in the trusted mode for external calls"
|
"Contract deployment is only supported in the trusted mode for external calls"
|
||||||
@ -737,7 +739,7 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall)
|
|||||||
case FunctionType::Kind::BareCallCode:
|
case FunctionType::Kind::BareCallCode:
|
||||||
case FunctionType::Kind::BareDelegateCall:
|
case FunctionType::Kind::BareDelegateCall:
|
||||||
default:
|
default:
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
4588_error,
|
4588_error,
|
||||||
_funCall.location(),
|
_funCall.location(),
|
||||||
"Assertion checker does not yet implement this type of function call."
|
"Assertion checker does not yet implement this type of function call."
|
||||||
@ -1406,7 +1408,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
|
|||||||
else
|
else
|
||||||
// NOTE: supporting name, creationCode, runtimeCode would be easy enough, but the bytes/string they return are not
|
// NOTE: supporting name, creationCode, runtimeCode would be easy enough, but the bytes/string they return are not
|
||||||
// at all usable in the SMT checker currently
|
// at all usable in the SMT checker currently
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
7507_error,
|
7507_error,
|
||||||
_memberAccess.location(),
|
_memberAccess.location(),
|
||||||
"Assertion checker does not yet support this expression."
|
"Assertion checker does not yet support this expression."
|
||||||
@ -1497,7 +1499,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
7650_error,
|
7650_error,
|
||||||
_memberAccess.location(),
|
_memberAccess.location(),
|
||||||
"Assertion checker does not yet support this expression."
|
"Assertion checker does not yet support this expression."
|
||||||
@ -1628,7 +1630,7 @@ void SMTEncoder::indexOrMemberAssignment(Expression const& _expr, smtutil::Expre
|
|||||||
structType && structType->recursive()
|
structType && structType->recursive()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
4375_error,
|
4375_error,
|
||||||
memberAccess->location(),
|
memberAccess->location(),
|
||||||
"Assertion checker does not support recursive structs."
|
"Assertion checker does not support recursive structs."
|
||||||
@ -1742,7 +1744,7 @@ void SMTEncoder::defineGlobalVariable(string const& _name, Expression const& _ex
|
|||||||
{
|
{
|
||||||
bool abstract = m_context.createGlobalSymbol(_name, _expr);
|
bool abstract = m_context.createGlobalSymbol(_name, _expr);
|
||||||
if (abstract)
|
if (abstract)
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
1695_error,
|
1695_error,
|
||||||
_expr.location(),
|
_expr.location(),
|
||||||
"Assertion checker does not yet support this global variable."
|
"Assertion checker does not yet support this global variable."
|
||||||
@ -1793,7 +1795,7 @@ void SMTEncoder::arithmeticOperation(BinaryOperation const& _op)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
5188_error,
|
5188_error,
|
||||||
_op.location(),
|
_op.location(),
|
||||||
"Assertion checker does not yet implement this operator."
|
"Assertion checker does not yet implement this operator."
|
||||||
@ -1980,7 +1982,7 @@ void SMTEncoder::compareOperation(BinaryOperation const& _op)
|
|||||||
defineExpr(_op, *value);
|
defineExpr(_op, *value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
7229_error,
|
7229_error,
|
||||||
_op.location(),
|
_op.location(),
|
||||||
"Assertion checker does not yet implement the type " + _op.annotation().commonType->toString() + " for comparisons"
|
"Assertion checker does not yet implement the type " + _op.annotation().commonType->toString() + " for comparisons"
|
||||||
@ -2507,7 +2509,7 @@ bool SMTEncoder::createVariable(VariableDeclaration const& _varDecl)
|
|||||||
bool abstract = m_context.createVariable(_varDecl);
|
bool abstract = m_context.createVariable(_varDecl);
|
||||||
if (abstract)
|
if (abstract)
|
||||||
{
|
{
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
8115_error,
|
8115_error,
|
||||||
_varDecl.location(),
|
_varDecl.location(),
|
||||||
"Assertion checker does not yet support the type of this variable."
|
"Assertion checker does not yet support the type of this variable."
|
||||||
@ -2521,7 +2523,7 @@ smtutil::Expression SMTEncoder::expr(Expression const& _e, Type const* _targetTy
|
|||||||
{
|
{
|
||||||
if (!m_context.knownExpression(_e))
|
if (!m_context.knownExpression(_e))
|
||||||
{
|
{
|
||||||
m_errorReporter.warning(6031_error, _e.location(), "Internal error: Expression undefined for SMT solver." );
|
m_unsupportedErrors.warning(6031_error, _e.location(), "Internal error: Expression undefined for SMT solver." );
|
||||||
createExpr(_e);
|
createExpr(_e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2532,7 +2534,7 @@ void SMTEncoder::createExpr(Expression const& _e)
|
|||||||
{
|
{
|
||||||
bool abstract = m_context.createExpression(_e);
|
bool abstract = m_context.createExpression(_e);
|
||||||
if (abstract)
|
if (abstract)
|
||||||
m_errorReporter.warning(
|
m_unsupportedErrors.warning(
|
||||||
8364_error,
|
8364_error,
|
||||||
_e.location(),
|
_e.location(),
|
||||||
"Assertion checker does not yet implement type " + _e.annotation().type->toString()
|
"Assertion checker does not yet implement type " + _e.annotation().type->toString()
|
||||||
|
@ -56,6 +56,7 @@ public:
|
|||||||
smt::EncodingContext& _context,
|
smt::EncodingContext& _context,
|
||||||
ModelCheckerSettings _settings,
|
ModelCheckerSettings _settings,
|
||||||
langutil::UniqueErrorReporter& _errorReporter,
|
langutil::UniqueErrorReporter& _errorReporter,
|
||||||
|
langutil::UniqueErrorReporter& _unsupportedErrorReporter,
|
||||||
langutil::CharStreamProvider const& _charStreamProvider
|
langutil::CharStreamProvider const& _charStreamProvider
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -440,6 +441,7 @@ protected:
|
|||||||
bool m_checked = true;
|
bool m_checked = true;
|
||||||
|
|
||||||
langutil::UniqueErrorReporter& m_errorReporter;
|
langutil::UniqueErrorReporter& m_errorReporter;
|
||||||
|
langutil::UniqueErrorReporter& m_unsupportedErrors;
|
||||||
|
|
||||||
/// Stores the current function/modifier call/invocation path.
|
/// Stores the current function/modifier call/invocation path.
|
||||||
std::vector<CallStackEntry> m_callStack;
|
std::vector<CallStackEntry> m_callStack;
|
||||||
|
@ -445,7 +445,7 @@ std::optional<Json::Value> checkSettingsKeys(Json::Value const& _input)
|
|||||||
|
|
||||||
std::optional<Json::Value> checkModelCheckerSettingsKeys(Json::Value const& _input)
|
std::optional<Json::Value> checkModelCheckerSettingsKeys(Json::Value const& _input)
|
||||||
{
|
{
|
||||||
static set<string> keys{"contracts", "divModNoSlacks", "engine", "extCalls", "invariants", "showProvedSafe", "showUnproved", "solvers", "targets", "timeout"};
|
static set<string> keys{"contracts", "divModNoSlacks", "engine", "extCalls", "invariants", "showProvedSafe", "showUnproved", "showUnsupported", "solvers", "targets", "timeout"};
|
||||||
return checkKeys(_input, keys, "modelChecker");
|
return checkKeys(_input, keys, "modelChecker");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,6 +1063,14 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
|
|||||||
ret.modelCheckerSettings.showUnproved = showUnproved.asBool();
|
ret.modelCheckerSettings.showUnproved = showUnproved.asBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (modelCheckerSettings.isMember("showUnsupported"))
|
||||||
|
{
|
||||||
|
auto const& showUnsupported = modelCheckerSettings["showUnsupported"];
|
||||||
|
if (!showUnsupported.isBool())
|
||||||
|
return formatFatalError(Error::Type::JSONError, "settings.modelChecker.showUnsupported must be a Boolean value.");
|
||||||
|
ret.modelCheckerSettings.showUnsupported = showUnsupported.asBool();
|
||||||
|
}
|
||||||
|
|
||||||
if (modelCheckerSettings.isMember("solvers"))
|
if (modelCheckerSettings.isMember("solvers"))
|
||||||
{
|
{
|
||||||
auto const& solversArray = modelCheckerSettings["solvers"];
|
auto const& solversArray = modelCheckerSettings["solvers"];
|
||||||
|
@ -73,6 +73,7 @@ static string const g_strModelCheckerExtCalls = "model-checker-ext-calls";
|
|||||||
static string const g_strModelCheckerInvariants = "model-checker-invariants";
|
static string const g_strModelCheckerInvariants = "model-checker-invariants";
|
||||||
static string const g_strModelCheckerShowProvedSafe = "model-checker-show-proved-safe";
|
static string const g_strModelCheckerShowProvedSafe = "model-checker-show-proved-safe";
|
||||||
static string const g_strModelCheckerShowUnproved = "model-checker-show-unproved";
|
static string const g_strModelCheckerShowUnproved = "model-checker-show-unproved";
|
||||||
|
static string const g_strModelCheckerShowUnsupported = "model-checker-show-unsupported";
|
||||||
static string const g_strModelCheckerSolvers = "model-checker-solvers";
|
static string const g_strModelCheckerSolvers = "model-checker-solvers";
|
||||||
static string const g_strModelCheckerTargets = "model-checker-targets";
|
static string const g_strModelCheckerTargets = "model-checker-targets";
|
||||||
static string const g_strModelCheckerTimeout = "model-checker-timeout";
|
static string const g_strModelCheckerTimeout = "model-checker-timeout";
|
||||||
@ -854,6 +855,10 @@ General Information)").c_str(),
|
|||||||
g_strModelCheckerShowUnproved.c_str(),
|
g_strModelCheckerShowUnproved.c_str(),
|
||||||
"Show all unproved targets separately."
|
"Show all unproved targets separately."
|
||||||
)
|
)
|
||||||
|
(
|
||||||
|
g_strModelCheckerShowUnsupported.c_str(),
|
||||||
|
"Show all unsupported language features separately."
|
||||||
|
)
|
||||||
(
|
(
|
||||||
g_strModelCheckerSolvers.c_str(),
|
g_strModelCheckerSolvers.c_str(),
|
||||||
po::value<string>()->value_name("cvc4,eld,z3,smtlib2")->default_value("z3"),
|
po::value<string>()->value_name("cvc4,eld,z3,smtlib2")->default_value("z3"),
|
||||||
@ -960,6 +965,7 @@ void CommandLineParser::processArgs()
|
|||||||
{g_strMetadataHash, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
{g_strMetadataHash, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
||||||
{g_strModelCheckerShowProvedSafe, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
{g_strModelCheckerShowProvedSafe, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
||||||
{g_strModelCheckerShowUnproved, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
{g_strModelCheckerShowUnproved, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
||||||
|
{g_strModelCheckerShowUnsupported, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
||||||
{g_strModelCheckerDivModNoSlacks, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
{g_strModelCheckerDivModNoSlacks, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
||||||
{g_strModelCheckerEngine, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
{g_strModelCheckerEngine, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
||||||
{g_strModelCheckerInvariants, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
{g_strModelCheckerInvariants, {InputMode::Compiler, InputMode::CompilerWithASTImport}},
|
||||||
@ -1326,6 +1332,9 @@ void CommandLineParser::processArgs()
|
|||||||
if (m_args.count(g_strModelCheckerShowUnproved))
|
if (m_args.count(g_strModelCheckerShowUnproved))
|
||||||
m_options.modelChecker.settings.showUnproved = true;
|
m_options.modelChecker.settings.showUnproved = true;
|
||||||
|
|
||||||
|
if (m_args.count(g_strModelCheckerShowUnsupported))
|
||||||
|
m_options.modelChecker.settings.showUnsupported = true;
|
||||||
|
|
||||||
if (m_args.count(g_strModelCheckerSolvers))
|
if (m_args.count(g_strModelCheckerSolvers))
|
||||||
{
|
{
|
||||||
string solversStr = m_args[g_strModelCheckerSolvers].as<string>();
|
string solversStr = m_args[g_strModelCheckerSolvers].as<string>();
|
||||||
@ -1356,6 +1365,7 @@ void CommandLineParser::processArgs()
|
|||||||
m_args.count(g_strModelCheckerInvariants) ||
|
m_args.count(g_strModelCheckerInvariants) ||
|
||||||
m_args.count(g_strModelCheckerShowProvedSafe) ||
|
m_args.count(g_strModelCheckerShowProvedSafe) ||
|
||||||
m_args.count(g_strModelCheckerShowUnproved) ||
|
m_args.count(g_strModelCheckerShowUnproved) ||
|
||||||
|
m_args.count(g_strModelCheckerShowUnsupported) ||
|
||||||
m_args.count(g_strModelCheckerSolvers) ||
|
m_args.count(g_strModelCheckerSolvers) ||
|
||||||
m_args.count(g_strModelCheckerTargets) ||
|
m_args.count(g_strModelCheckerTargets) ||
|
||||||
m_args.count(g_strModelCheckerTimeout);
|
m_args.count(g_strModelCheckerTimeout);
|
||||||
|
@ -47,6 +47,14 @@ SMTCheckerTest::SMTCheckerTest(string const& _filename): SyntaxTest(_filename, E
|
|||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(runtime_error("Invalid SMT \"show unproved\" choice."));
|
BOOST_THROW_EXCEPTION(runtime_error("Invalid SMT \"show unproved\" choice."));
|
||||||
|
|
||||||
|
auto const& showUnsupported = m_reader.stringSetting("SMTShowUnsupported", "yes");
|
||||||
|
if (showUnsupported == "no")
|
||||||
|
m_modelCheckerSettings.showUnsupported = false;
|
||||||
|
else if (showUnsupported == "yes")
|
||||||
|
m_modelCheckerSettings.showUnsupported = true;
|
||||||
|
else
|
||||||
|
BOOST_THROW_EXCEPTION(runtime_error("Invalid SMT \"show unsupported\" choice."));
|
||||||
|
|
||||||
m_modelCheckerSettings.solvers = smtutil::SMTSolverChoice::None();
|
m_modelCheckerSettings.solvers = smtutil::SMTSolverChoice::None();
|
||||||
auto const& choice = m_reader.stringSetting("SMTSolvers", "z3");
|
auto const& choice = m_reader.stringSetting("SMTSolvers", "z3");
|
||||||
if (choice == "none")
|
if (choice == "none")
|
||||||
|
@ -16,7 +16,7 @@ contract C {
|
|||||||
// Warning 6031: (182-186): Internal error: Expression undefined for SMT solver.
|
// Warning 6031: (182-186): Internal error: Expression undefined for SMT solver.
|
||||||
// Warning 6031: (190-194): Internal error: Expression undefined for SMT solver.
|
// Warning 6031: (190-194): Internal error: Expression undefined for SMT solver.
|
||||||
// Warning 7229: (206-212): Assertion checker does not yet implement the type function (uint256) returns (uint256) for comparisons
|
// Warning 7229: (206-212): Assertion checker does not yet implement the type function (uint256) returns (uint256) for comparisons
|
||||||
// Warning 6328: (175-195): CHC: Assertion violation happens here.\nCounterexample:\na = 0, b = 0\n\nTransaction trace:\nC.constructor()\nState: a = 0, b = 0\nC.g()\n C.f(0, 0) -- internal call
|
|
||||||
// Warning 6328: (199-213): CHC: Assertion violation happens here.\nCounterexample:\na = 0, b = 0\n\nTransaction trace:\nC.constructor()\nState: a = 0, b = 0\nC.g()\n C.f(0, 0) -- internal call
|
|
||||||
// Warning 5729: (182-186): BMC does not yet implement this type of function call.
|
// Warning 5729: (182-186): BMC does not yet implement this type of function call.
|
||||||
// Warning 5729: (190-194): BMC does not yet implement this type of function call.
|
// Warning 5729: (190-194): BMC does not yet implement this type of function call.
|
||||||
|
// Warning 6328: (175-195): CHC: Assertion violation happens here.
|
||||||
|
// Warning 6328: (199-213): CHC: Assertion violation happens here.
|
||||||
|
18
test/libsolidity/smtCheckerTests/unsupported/assembly_1.sol
Normal file
18
test/libsolidity/smtCheckerTests/unsupported/assembly_1.sol
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
contract C {
|
||||||
|
function f(uint x, uint y) public pure {
|
||||||
|
assembly {}
|
||||||
|
assert(x < y);
|
||||||
|
}
|
||||||
|
|
||||||
|
function g(uint x, uint y) public pure {
|
||||||
|
assembly {}
|
||||||
|
assert(x < y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// SMTEngine: all
|
||||||
|
// SMTShowUnsupported: no
|
||||||
|
// ----
|
||||||
|
// Warning 5724: SMTChecker: 2 unsupported language feature(s). Enable the model checker option "show unsupported" to see all of them.
|
||||||
|
// Warning 6328: (86-99): CHC: Assertion violation happens here.
|
||||||
|
// Warning 6328: (181-194): CHC: Assertion violation happens here.
|
@ -149,6 +149,7 @@ BOOST_AUTO_TEST_CASE(cli_mode_options)
|
|||||||
"--model-checker-invariants=contract,reentrancy",
|
"--model-checker-invariants=contract,reentrancy",
|
||||||
"--model-checker-show-proved-safe",
|
"--model-checker-show-proved-safe",
|
||||||
"--model-checker-show-unproved",
|
"--model-checker-show-unproved",
|
||||||
|
"--model-checker-show-unsupported",
|
||||||
"--model-checker-solvers=z3,smtlib2",
|
"--model-checker-solvers=z3,smtlib2",
|
||||||
"--model-checker-targets=underflow,divByZero",
|
"--model-checker-targets=underflow,divByZero",
|
||||||
"--model-checker-timeout=5",
|
"--model-checker-timeout=5",
|
||||||
@ -217,6 +218,7 @@ BOOST_AUTO_TEST_CASE(cli_mode_options)
|
|||||||
{{InvariantType::Contract, InvariantType::Reentrancy}},
|
{{InvariantType::Contract, InvariantType::Reentrancy}},
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
{false, false, true, true},
|
{false, false, true, true},
|
||||||
{{VerificationTargetType::Underflow, VerificationTargetType::DivByZero}},
|
{{VerificationTargetType::Underflow, VerificationTargetType::DivByZero}},
|
||||||
5,
|
5,
|
||||||
@ -414,6 +416,7 @@ BOOST_AUTO_TEST_CASE(invalid_options_input_modes_combinations)
|
|||||||
{"--metadata-hash=swarm", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
{"--metadata-hash=swarm", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
||||||
{"--model-checker-show-proved-safe", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
{"--model-checker-show-proved-safe", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
||||||
{"--model-checker-show-unproved", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
{"--model-checker-show-unproved", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
||||||
|
{"--model-checker-show-unsupported", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
||||||
{"--model-checker-div-mod-no-slacks", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
{"--model-checker-div-mod-no-slacks", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
||||||
{"--model-checker-engine=bmc", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
{"--model-checker-engine=bmc", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
||||||
{"--model-checker-invariants=contract,reentrancy", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
{"--model-checker-invariants=contract,reentrancy", {"--assemble", "--yul", "--strict-assembly", "--standard-json", "--link"}},
|
||||||
|
@ -112,6 +112,7 @@ void FuzzerUtil::testCompiler(
|
|||||||
frontend::ModelCheckerInvariants::All(),
|
frontend::ModelCheckerInvariants::All(),
|
||||||
/*showProvedSafe=*/false,
|
/*showProvedSafe=*/false,
|
||||||
/*showUnproved=*/false,
|
/*showUnproved=*/false,
|
||||||
|
/*showUnsupported=*/false,
|
||||||
smtutil::SMTSolverChoice::All(),
|
smtutil::SMTSolverChoice::All(),
|
||||||
frontend::ModelCheckerTargets::Default(),
|
frontend::ModelCheckerTargets::Default(),
|
||||||
/*timeout=*/1
|
/*timeout=*/1
|
||||||
|
Loading…
Reference in New Issue
Block a user