Skip to content

Commit 3c65632

Browse files
authored
Merge pull request #15205 from pgebal/smtchecker/fix-show-proved-safe
SMTChecker: Fix internal compiler error on reporting proved targets
2 parents 7711a8e + 6ccb3a3 commit 3c65632

34 files changed

+94
-34
lines changed

Changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ Compiler Features:
1212

1313

1414
Bugfixes:
15-
* SMTChecker: Fix error that reports invalid number of verified checks for BMC engine.
15+
* SMTChecker: Fix error that reports invalid number of verified checks for BMC and CHC engines.
16+
* SMTChecker: Fix internal compiler error when reporting proved targets for BMC engine.
1617
* TypeChecker: Fix segfault when assigning nested tuple to tuple.
1718
* Yul Optimizer: Name simplification could lead to forbidden identifiers with a leading and/or trailing dot, e.g., ``x._`` would get simplified into ``x.``.
1819

libsolidity/formal/BMC.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,13 @@ BMC::BMC(
4747
smt::EncodingContext& _context,
4848
UniqueErrorReporter& _errorReporter,
4949
UniqueErrorReporter& _unsupportedErrorReporter,
50+
ErrorReporter& _provedSafeReporter,
5051
std::map<h256, std::string> const& _smtlib2Responses,
5152
ReadCallback::Callback const& _smtCallback,
5253
ModelCheckerSettings _settings,
5354
CharStreamProvider const& _charStreamProvider
5455
):
55-
SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider)
56+
SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider)
5657
{
5758
solAssert(!_settings.printQuery || _settings.solvers == SMTSolverChoice::SMTLIB2(), "Only SMTLib2 solver can be enabled to print queries");
5859
std::vector<std::unique_ptr<SolverInterface>> solvers;
@@ -133,15 +134,14 @@ void BMC::analyze(SourceUnit const& _source, std::map<ASTNode const*, std::set<V
133134
else if (m_settings.showProvedSafe)
134135
for (auto const& [node, targets]: m_safeTargets)
135136
for (auto const& target: targets)
136-
m_errorReporter.info(
137+
m_provedSafeReporter.info(
137138
2961_error,
138139
node->location(),
139140
"BMC: " +
140141
targetDescription(target) +
141142
" check is safe!"
142143
);
143144

144-
145145
// If this check is true, Z3 and cvc5 are not available
146146
// and the query answers were not provided, since SMTPortfolio
147147
// guarantees that SmtLib2Interface is the first solver, if enabled.

libsolidity/formal/BMC.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class BMC: public SMTEncoder
6262
smt::EncodingContext& _context,
6363
langutil::UniqueErrorReporter& _errorReporter,
6464
langutil::UniqueErrorReporter& _unsupportedErrorReporter,
65+
langutil::ErrorReporter& _provedSafeReporter,
6566
std::map<h256, std::string> const& _smtlib2Responses,
6667
ReadCallback::Callback const& _smtCallback,
6768
ModelCheckerSettings _settings,

libsolidity/formal/CHC.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,13 @@ CHC::CHC(
6363
EncodingContext& _context,
6464
UniqueErrorReporter& _errorReporter,
6565
UniqueErrorReporter& _unsupportedErrorReporter,
66+
ErrorReporter& _provedSafeReporter,
6667
std::map<util::h256, std::string> const& _smtlib2Responses,
6768
ReadCallback::Callback const& _smtCallback,
6869
ModelCheckerSettings _settings,
6970
CharStreamProvider const& _charStreamProvider
7071
):
71-
SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _charStreamProvider),
72+
SMTEncoder(_context, _settings, _errorReporter, _unsupportedErrorReporter, _provedSafeReporter, _charStreamProvider),
7273
m_smtlib2Responses(_smtlib2Responses),
7374
m_smtCallback(_smtCallback)
7475
{
@@ -2116,17 +2117,22 @@ void CHC::checkVerificationTargets()
21162117
);
21172118

21182119
if (!m_settings.showProvedSafe && !m_safeTargets.empty())
2120+
{
2121+
std::size_t provedSafeNum = 0;
2122+
for (auto&& [_, targets]: m_safeTargets)
2123+
provedSafeNum += targets.size();
21192124
m_errorReporter.info(
21202125
1391_error,
21212126
"CHC: " +
2122-
std::to_string(m_safeTargets.size()) +
2127+
std::to_string(provedSafeNum) +
21232128
" verification condition(s) proved safe!" +
21242129
" Enable the model checker option \"show proved safe\" to see all of them."
21252130
);
2131+
}
21262132
else if (m_settings.showProvedSafe)
21272133
for (auto const& [node, targets]: m_safeTargets)
21282134
for (auto const& target: targets)
2129-
m_errorReporter.info(
2135+
m_provedSafeReporter.info(
21302136
9576_error,
21312137
node->location(),
21322138
"CHC: " +

libsolidity/formal/CHC.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class CHC: public SMTEncoder
5858
smt::EncodingContext& _context,
5959
langutil::UniqueErrorReporter& _errorReporter,
6060
langutil::UniqueErrorReporter& _unsupportedErrorReporter,
61+
langutil::ErrorReporter& _provedSafeReporter,
6162
std::map<util::h256, std::string> const& _smtlib2Responses,
6263
ReadCallback::Callback const& _smtCallback,
6364
ModelCheckerSettings _settings,
@@ -77,14 +78,25 @@ class CHC: public SMTEncoder
7778
}
7879
};
7980

81+
struct SafeTargetsCompare
82+
{
83+
bool operator()(CHCVerificationTarget const & _lhs, CHCVerificationTarget const & _rhs) const
84+
{
85+
if (_lhs.errorNode->id() == _rhs.errorNode->id())
86+
return _lhs.type < _rhs.type;
87+
else
88+
return _lhs.errorNode->id() == _rhs.errorNode->id();
89+
}
90+
};
91+
8092
struct ReportTargetInfo
8193
{
8294
langutil::ErrorId error;
8395
langutil::SourceLocation location;
8496
std::string message;
8597
};
8698

87-
std::map<ASTNode const*, std::set<CHCVerificationTarget>, smt::EncodingContext::IdCompare> const& safeTargets() const { return m_safeTargets; }
99+
std::map<ASTNode const*, std::set<CHCVerificationTarget, SafeTargetsCompare>, smt::EncodingContext::IdCompare> const& safeTargets() const { return m_safeTargets; }
88100
std::map<ASTNode const*, std::map<VerificationTargetType, ReportTargetInfo>, smt::EncodingContext::IdCompare> const& unsafeTargets() const { return m_unsafeTargets; }
89101

90102
/// This is used if the Horn solver is not directly linked into this binary.
@@ -423,7 +435,7 @@ class CHC: public SMTEncoder
423435
std::map<unsigned, CHCVerificationTarget> m_verificationTargets;
424436

425437
/// Targets proved safe.
426-
std::map<ASTNode const*, std::set<CHCVerificationTarget>, smt::EncodingContext::IdCompare> m_safeTargets;
438+
std::map<ASTNode const*, std::set<CHCVerificationTarget, SafeTargetsCompare>, smt::EncodingContext::IdCompare> m_safeTargets;
427439
/// Targets proved unsafe.
428440
std::map<ASTNode const*, std::map<VerificationTargetType, ReportTargetInfo>, smt::EncodingContext::IdCompare> m_unsafeTargets;
429441
/// Targets not proved.

libsolidity/formal/ModelChecker.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ ModelChecker::ModelChecker(
4343
ReadCallback::Callback const& _smtCallback
4444
):
4545
m_errorReporter(_errorReporter),
46+
m_provedSafeReporter(m_provedSafeLogs),
4647
m_settings(std::move(_settings)),
4748
m_context(),
48-
m_bmc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider),
49-
m_chc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider)
49+
m_bmc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, m_provedSafeReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider),
50+
m_chc(m_context, m_uniqueErrorReporter, m_unsupportedErrorReporter, m_provedSafeReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider)
5051
{
5152
}
5253

@@ -151,6 +152,12 @@ void ModelChecker::analyze(SourceUnit const& _source)
151152

152153
m_errorReporter.append(m_uniqueErrorReporter.errors());
153154
m_uniqueErrorReporter.clear();
155+
156+
if (m_settings.showProvedSafe)
157+
{
158+
m_errorReporter.append(m_provedSafeReporter.errors());
159+
m_provedSafeReporter.clear();
160+
}
154161
}
155162

156163
std::vector<std::string> ModelChecker::unhandledQueries()

libsolidity/formal/ModelChecker.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ class ModelChecker
9595
/// to m_errorReporter at the end of the analysis.
9696
langutil::UniqueErrorReporter m_unsupportedErrorReporter;
9797

98+
langutil::ErrorList m_provedSafeLogs;
99+
/// Used by SMTEncoder, BMC and CHC to accumulate info about proved targets.
100+
/// This is local to ModelChecker, so needs to be appended
101+
/// to m_errorReporter at the end of the analysis.
102+
langutil::ErrorReporter m_provedSafeReporter;
103+
98104
ModelCheckerSettings m_settings;
99105

100106
/// Stores the context of the encoding.

libsolidity/formal/SMTEncoder.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ SMTEncoder::SMTEncoder(
5151
ModelCheckerSettings _settings,
5252
UniqueErrorReporter& _errorReporter,
5353
UniqueErrorReporter& _unsupportedErrorReporter,
54+
ErrorReporter& _provedSafeReporter,
5455
langutil::CharStreamProvider const& _charStreamProvider
5556
):
5657
m_errorReporter(_errorReporter),
5758
m_unsupportedErrors(_unsupportedErrorReporter),
59+
m_provedSafeReporter(_provedSafeReporter),
5860
m_context(_context),
5961
m_settings(std::move(_settings)),
6062
m_charStreamProvider(_charStreamProvider)

libsolidity/formal/SMTEncoder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class SMTEncoder: public ASTConstVisitor
5757
ModelCheckerSettings _settings,
5858
langutil::UniqueErrorReporter& _errorReporter,
5959
langutil::UniqueErrorReporter& _unsupportedErrorReporter,
60+
langutil::ErrorReporter& _provedSafeReporter,
6061
langutil::CharStreamProvider const& _charStreamProvider
6162
);
6263

@@ -463,6 +464,7 @@ class SMTEncoder: public ASTConstVisitor
463464

464465
langutil::UniqueErrorReporter& m_errorReporter;
465466
langutil::UniqueErrorReporter& m_unsupportedErrors;
467+
langutil::ErrorReporter& m_provedSafeReporter;
466468

467469
/// Stores the current function/modifier call/invocation path.
468470
std::vector<CallStackEntry> m_callStack;

scripts/error_codes.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
205205
"7053", # Unimplemented feature error (parsing stage), currently has no tests
206206
"1180", # SMTChecker, covered by CL tests
207207
"2339", # SMTChecker, covered by CL tests
208-
"2961", # SMTChecker, covered by CL tests
209208
"6240", # SMTChecker, covered by CL tests
210209
}
211210
assert len(test_ids & white_ids) == 0, "The sets are not supposed to intersect"

0 commit comments

Comments
 (0)