Skip to content

Commit ab6b430

Browse files
author
Leonardo
authored
Merge pull request #11850 from ethereum/smt_remove_redundant_warnings
[SMTChecker] Remove redundant unsupported warnings
2 parents 327571d + 0cc9162 commit ab6b430

File tree

76 files changed

+142
-432
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+142
-432
lines changed

liblangutil/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ set(sources
2525
Token.cpp
2626
Token.h
2727
UndefMacros.h
28+
UniqueErrorReporter.h
2829
)
2930

3031
add_library(langutil ${sources})

liblangutil/Exceptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ struct ErrorId
105105
unsigned long long error = 0;
106106
bool operator==(ErrorId const& _rhs) const { return error == _rhs.error; }
107107
bool operator!=(ErrorId const& _rhs) const { return !(*this == _rhs); }
108+
bool operator<(ErrorId const& _rhs) const { return error < _rhs.error; }
108109
};
109110
constexpr ErrorId operator"" _error(unsigned long long _error) { return ErrorId{ _error }; }
110111

liblangutil/UniqueErrorReporter.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
This file is part of solidity.
3+
4+
solidity is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
solidity is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with solidity. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
// SPDX-License-Identifier: GPL-3.0
18+
19+
#pragma once
20+
21+
#include <liblangutil/ErrorReporter.h>
22+
#include <liblangutil/Exceptions.h>
23+
24+
namespace solidity::langutil
25+
{
26+
27+
/*
28+
* Wrapper for ErrorReporter that removes duplicates.
29+
* Two errors are considered the same if their error ID and location are the same.
30+
*/
31+
class UniqueErrorReporter
32+
{
33+
public:
34+
UniqueErrorReporter(): m_errorReporter(m_uniqueErrors) {}
35+
36+
void warning(ErrorId _error, SourceLocation const& _location, std::string const& _description)
37+
{
38+
if (!seen(_error, _location, _description))
39+
{
40+
m_errorReporter.warning(_error, _location, _description);
41+
markAsSeen(_error, _location, _description);
42+
}
43+
}
44+
45+
void warning(
46+
ErrorId _error,
47+
SourceLocation const& _location,
48+
std::string const& _description,
49+
SecondarySourceLocation const& _secondaryLocation
50+
)
51+
{
52+
if (!seen(_error, _location, _description))
53+
{
54+
m_errorReporter.warning(_error, _location, _description, _secondaryLocation);
55+
markAsSeen(_error, _location, _description);
56+
}
57+
}
58+
59+
void warning(ErrorId _error, std::string const& _description)
60+
{
61+
if (!seen(_error, {}, _description))
62+
{
63+
m_errorReporter.warning(_error, _description);
64+
markAsSeen(_error, {}, _description);
65+
}
66+
}
67+
68+
bool seen(ErrorId _error, SourceLocation const& _location, std::string const& _description) const
69+
{
70+
if (m_seenErrors.count({_error, _location}))
71+
{
72+
solAssert(m_seenErrors.at({_error, _location}) == _description, "");
73+
return true;
74+
}
75+
return false;
76+
}
77+
78+
void markAsSeen(ErrorId _error, SourceLocation const& _location, std::string const& _description)
79+
{
80+
solAssert(!seen(_error, _location, _description), "");
81+
m_seenErrors[{_error, _location}] = _description;
82+
}
83+
84+
ErrorList const& errors() const { return m_errorReporter.errors(); }
85+
86+
void clear() { m_errorReporter.clear(); }
87+
88+
private:
89+
ErrorReporter m_errorReporter;
90+
ErrorList m_uniqueErrors;
91+
std::map<std::pair<ErrorId, SourceLocation>, std::string> m_seenErrors;
92+
};
93+
94+
}

libsolidity/formal/BMC.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,14 @@ using namespace solidity::frontend;
3737

3838
BMC::BMC(
3939
smt::EncodingContext& _context,
40-
ErrorReporter& _errorReporter,
40+
UniqueErrorReporter& _errorReporter,
4141
map<h256, string> const& _smtlib2Responses,
4242
ReadCallback::Callback const& _smtCallback,
4343
ModelCheckerSettings const& _settings,
4444
CharStreamProvider const& _charStreamProvider
4545
):
46-
SMTEncoder(_context, _settings, _charStreamProvider),
47-
m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _settings.solvers, _settings.timeout)),
48-
m_outerErrorReporter(_errorReporter)
46+
SMTEncoder(_context, _settings, _errorReporter, _charStreamProvider),
47+
m_interface(make_unique<smtutil::SMTPortfolio>(_smtlib2Responses, _smtCallback, _settings.solvers, _settings.timeout))
4948
{
5049
#if defined (HAVE_Z3) || defined (HAVE_CVC4)
5150
if (m_settings.solvers.cvc4 || m_settings.solvers.z3)
@@ -67,7 +66,7 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
6766
if (!m_noSolverWarning)
6867
{
6968
m_noSolverWarning = true;
70-
m_outerErrorReporter.warning(
69+
m_errorReporter.warning(
7170
7710_error,
7271
SourceLocation(),
7372
"BMC analysis was not possible since no SMT solver was found and enabled."
@@ -113,7 +112,7 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
113112
if (!m_noSolverWarning)
114113
{
115114
m_noSolverWarning = true;
116-
m_outerErrorReporter.warning(
115+
m_errorReporter.warning(
117116
8084_error,
118117
SourceLocation(),
119118
"BMC analysis was not possible. No SMT solver (Z3 or CVC4) was available."
@@ -124,10 +123,6 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
124123
);
125124
}
126125
}
127-
else
128-
m_outerErrorReporter.append(m_errorReporter.errors());
129-
130-
m_errorReporter.clear();
131126
}
132127

133128
bool BMC::shouldInlineFunctionCall(

libsolidity/formal/BMC.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include <libsolidity/interface/ReadFile.h>
3737

3838
#include <libsmtutil/SolverInterface.h>
39-
#include <liblangutil/ErrorReporter.h>
39+
#include <liblangutil/UniqueErrorReporter.h>
4040

4141
#include <set>
4242
#include <string>
@@ -59,7 +59,7 @@ class BMC: public SMTEncoder
5959
public:
6060
BMC(
6161
smt::EncodingContext& _context,
62-
langutil::ErrorReporter& _errorReporter,
62+
langutil::UniqueErrorReporter& _errorReporter,
6363
std::map<h256, std::string> const& _smtlib2Responses,
6464
ReadCallback::Callback const& _smtCallback,
6565
ModelCheckerSettings const& _settings,
@@ -186,9 +186,6 @@ class BMC: public SMTEncoder
186186
bool m_loopExecutionHappened = false;
187187
bool m_externalFunctionCallHappened = false;
188188

189-
/// ErrorReporter that comes from CompilerStack.
190-
langutil::ErrorReporter& m_outerErrorReporter;
191-
192189
std::vector<BMCVerificationTarget> m_verificationTargets;
193190

194191
/// Targets that were already proven.

libsolidity/formal/CHC.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,13 @@ using namespace solidity::frontend::smt;
5353

5454
CHC::CHC(
5555
EncodingContext& _context,
56-
ErrorReporter& _errorReporter,
56+
UniqueErrorReporter& _errorReporter,
5757
[[maybe_unused]] map<util::h256, string> const& _smtlib2Responses,
5858
[[maybe_unused]] ReadCallback::Callback const& _smtCallback,
5959
ModelCheckerSettings const& _settings,
6060
CharStreamProvider const& _charStreamProvider
6161
):
62-
SMTEncoder(_context, _settings, _charStreamProvider),
63-
m_outerErrorReporter(_errorReporter)
62+
SMTEncoder(_context, _settings, _errorReporter, _charStreamProvider)
6463
{
6564
bool usesZ3 = m_settings.solvers.z3;
6665
#ifdef HAVE_Z3
@@ -79,7 +78,7 @@ void CHC::analyze(SourceUnit const& _source)
7978
if (!m_noSolverWarning)
8079
{
8180
m_noSolverWarning = true;
82-
m_outerErrorReporter.warning(
81+
m_errorReporter.warning(
8382
7649_error,
8483
SourceLocation(),
8584
"CHC analysis was not possible since no Horn solver was enabled."
@@ -111,7 +110,7 @@ void CHC::analyze(SourceUnit const& _source)
111110
if (!ranSolver && !m_noSolverWarning)
112111
{
113112
m_noSolverWarning = true;
114-
m_outerErrorReporter.warning(
113+
m_errorReporter.warning(
115114
3996_error,
116115
SourceLocation(),
117116
#ifdef HAVE_Z3_DLOPEN
@@ -122,10 +121,6 @@ void CHC::analyze(SourceUnit const& _source)
122121
#endif
123122
);
124123
}
125-
else
126-
m_outerErrorReporter.append(m_errorReporter.errors());
127-
128-
m_errorReporter.clear();
129124
}
130125

131126
vector<string> CHC::unhandledQueries() const

libsolidity/formal/CHC.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <libsmtutil/CHCSolverInterface.h>
4141

4242
#include <liblangutil/SourceLocation.h>
43+
#include <liblangutil/UniqueErrorReporter.h>
4344

4445
#include <boost/algorithm/string/join.hpp>
4546

@@ -55,7 +56,7 @@ class CHC: public SMTEncoder
5556
public:
5657
CHC(
5758
smt::EncodingContext& _context,
58-
langutil::ErrorReporter& _errorReporter,
59+
langutil::UniqueErrorReporter& _errorReporter,
5960
std::map<util::h256, std::string> const& _smtlib2Responses,
6061
ReadCallback::Callback const& _smtCallback,
6162
ModelCheckerSettings const& _settings,
@@ -415,9 +416,6 @@ class CHC: public SMTEncoder
415416

416417
/// CHC solver.
417418
std::unique_ptr<smtutil::CHCSolverInterface> m_interface;
418-
419-
/// ErrorReporter that comes from CompilerStack.
420-
langutil::ErrorReporter& m_outerErrorReporter;
421419
};
422420

423421
}

libsolidity/formal/ModelChecker.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ ModelChecker::ModelChecker(
4040
m_errorReporter(_errorReporter),
4141
m_settings(move(_settings)),
4242
m_context(),
43-
m_bmc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider),
44-
m_chc(m_context, _errorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider)
43+
m_bmc(m_context, m_uniqueErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider),
44+
m_chc(m_context, m_uniqueErrorReporter, _smtlib2Responses, _smtCallback, m_settings, _charStreamProvider)
4545
{
4646
}
4747

@@ -68,7 +68,7 @@ void ModelChecker::checkRequestedSourcesAndContracts(vector<shared_ptr<SourceUni
6868
{
6969
if (!exist.count(sourceName))
7070
{
71-
m_errorReporter.warning(
71+
m_uniqueErrorReporter.warning(
7272
9134_error,
7373
SourceLocation(),
7474
"Requested source \"" + sourceName + "\" does not exist."
@@ -79,7 +79,7 @@ void ModelChecker::checkRequestedSourcesAndContracts(vector<shared_ptr<SourceUni
7979
// Requested contracts in source `s`.
8080
for (auto const& contract: m_settings.contracts.contracts.at(sourceName))
8181
if (!source.count(contract))
82-
m_errorReporter.warning(
82+
m_uniqueErrorReporter.warning(
8383
7400_error,
8484
SourceLocation(),
8585
"Requested contract \"" + contract + "\" does not exist in source \"" + sourceName + "\"."
@@ -104,7 +104,7 @@ void ModelChecker::analyze(SourceUnit const& _source)
104104
break;
105105
}
106106
solAssert(smtPragma, "");
107-
m_errorReporter.warning(
107+
m_uniqueErrorReporter.warning(
108108
5523_error,
109109
smtPragma->location(),
110110
"The SMTChecker pragma has been deprecated and will be removed in the future. "
@@ -125,6 +125,9 @@ void ModelChecker::analyze(SourceUnit const& _source)
125125

126126
if (m_settings.engine.bmc)
127127
m_bmc.analyze(_source, solvedTargets);
128+
129+
m_errorReporter.append(m_uniqueErrorReporter.errors());
130+
m_uniqueErrorReporter.clear();
128131
}
129132

130133
vector<string> ModelChecker::unhandledQueries()

libsolidity/formal/ModelChecker.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
#include <libsolidity/interface/ReadFile.h>
3232

3333
#include <libsmtutil/SolverInterface.h>
34+
3435
#include <liblangutil/ErrorReporter.h>
36+
#include <liblangutil/UniqueErrorReporter.h>
3537

3638
namespace solidity::langutil
3739
{
@@ -73,8 +75,16 @@ class ModelChecker
7375
static smtutil::SMTSolverChoice availableSolvers();
7476

7577
private:
78+
/// Error reporter from CompilerStack.
79+
/// We need to append m_uniqueErrorReporter
80+
/// to this one when the analysis is done.
7681
langutil::ErrorReporter& m_errorReporter;
7782

83+
/// Used by ModelChecker, SMTEncoder, BMC and CHC to avoid duplicates.
84+
/// This is local to ModelChecker, so needs to be appended
85+
/// to m_errorReporter at the end of the analysis.
86+
langutil::UniqueErrorReporter m_uniqueErrorReporter;
87+
7888
ModelCheckerSettings m_settings;
7989

8090
/// Stores the context of the encoding.

libsolidity/formal/SMTEncoder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ using namespace solidity::frontend;
4646
SMTEncoder::SMTEncoder(
4747
smt::EncodingContext& _context,
4848
ModelCheckerSettings const& _settings,
49+
UniqueErrorReporter& _errorReporter,
4950
langutil::CharStreamProvider const& _charStreamProvider
5051
):
51-
m_errorReporter(m_smtErrors),
52+
m_errorReporter(_errorReporter),
5253
m_context(_context),
5354
m_settings(_settings),
5455
m_charStreamProvider(_charStreamProvider)

0 commit comments

Comments
 (0)