Skip to content

Commit a3d8da2

Browse files
author
Leonardo
authored
Merge pull request #11852 from ethereum/smt_fix_at
Fix ICE on multi-source use of abi.*
2 parents ab6b430 + 60b866f commit a3d8da2

File tree

10 files changed

+74
-46
lines changed

10 files changed

+74
-46
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Compiler Features:
1212

1313
Bugfixes:
1414
* SMTChecker: Fix false positive in external calls from constructors.
15+
* SMTChecker: Fix internal error on some multi-source uses of ``abi.*``, cryptographic functions and constants.
1516

1617

1718

libsolidity/formal/BMC.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -75,30 +75,30 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
7575
return;
7676
}
7777

78-
if (SMTEncoder::analyze(_source))
79-
{
80-
m_solvedTargets = move(_solvedTargets);
81-
m_context.setSolver(m_interface.get());
82-
m_context.reset();
83-
m_context.setAssertionAccumulation(true);
84-
m_variableUsage.setFunctionInlining(shouldInlineFunctionCall);
85-
createFreeConstants(sourceDependencies(_source));
86-
m_unprovedAmt = 0;
78+
SMTEncoder::resetSourceAnalysis();
8779

88-
_source.accept(*this);
80+
m_solvedTargets = move(_solvedTargets);
81+
m_context.setSolver(m_interface.get());
82+
m_context.reset();
83+
m_context.setAssertionAccumulation(true);
84+
m_variableUsage.setFunctionInlining(shouldInlineFunctionCall);
85+
createFreeConstants(sourceDependencies(_source));
86+
state().prepareForSourceUnit(_source);
87+
m_unprovedAmt = 0;
8988

90-
if (m_unprovedAmt > 0 && !m_settings.showUnproved)
91-
m_errorReporter.warning(
92-
2788_error,
93-
{},
94-
"BMC: " +
95-
to_string(m_unprovedAmt) +
96-
" verification condition(s) could not be proved." +
97-
" Enable the model checker option \"show unproved\" to see all of them." +
98-
" Consider choosing a specific contract to be verified in order to reduce the solving problems." +
99-
" Consider increasing the timeout per query."
100-
);
101-
}
89+
_source.accept(*this);
90+
91+
if (m_unprovedAmt > 0 && !m_settings.showUnproved)
92+
m_errorReporter.warning(
93+
2788_error,
94+
{},
95+
"BMC: " +
96+
to_string(m_unprovedAmt) +
97+
" verification condition(s) could not be proved." +
98+
" Enable the model checker option \"show unproved\" to see all of them." +
99+
" Consider choosing a specific contract to be verified in order to reduce the solving problems." +
100+
" Consider increasing the timeout per query."
101+
);
102102

103103
// If this check is true, Z3 and CVC4 are not available
104104
// and the query answers were not provided, since SMTPortfolio

libsolidity/formal/CHC.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,19 @@ void CHC::analyze(SourceUnit const& _source)
8787
return;
8888
}
8989

90-
if (SMTEncoder::analyze(_source))
91-
{
92-
resetSourceAnalysis();
90+
resetSourceAnalysis();
9391

94-
auto sources = sourceDependencies(_source);
95-
collectFreeFunctions(sources);
96-
createFreeConstants(sources);
97-
for (auto const* source: sources)
98-
defineInterfacesAndSummaries(*source);
99-
for (auto const* source: sources)
100-
source->accept(*this);
92+
auto sources = sourceDependencies(_source);
93+
collectFreeFunctions(sources);
94+
createFreeConstants(sources);
95+
state().prepareForSourceUnit(_source);
10196

102-
checkVerificationTargets();
103-
}
97+
for (auto const* source: sources)
98+
defineInterfacesAndSummaries(*source);
99+
for (auto const* source: sources)
100+
source->accept(*this);
101+
102+
checkVerificationTargets();
104103

105104
bool ranSolver = true;
106105
// If ranSolver is true here it's because an SMT solver callback was
@@ -947,6 +946,8 @@ pair<smtutil::Expression, smtutil::Expression> CHC::arithmeticOperation(
947946

948947
void CHC::resetSourceAnalysis()
949948
{
949+
SMTEncoder::resetSourceAnalysis();
950+
950951
m_safeTargets.clear();
951952
m_unsafeTargets.clear();
952953
m_unprovedTargets.clear();

libsolidity/formal/SMTEncoder.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,9 @@ SMTEncoder::SMTEncoder(
5656
{
5757
}
5858

59-
bool SMTEncoder::analyze(SourceUnit const& _source)
59+
void SMTEncoder::resetSourceAnalysis()
6060
{
61-
state().prepareForSourceUnit(_source);
62-
63-
return true;
61+
m_freeFunctions.clear();
6462
}
6563

6664
bool SMTEncoder::visit(ContractDefinition const& _contract)

libsolidity/formal/SMTEncoder.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@ class SMTEncoder: public ASTConstVisitor
5959
langutil::CharStreamProvider const& _charStreamProvider
6060
);
6161

62-
/// @returns true if engine should proceed with analysis.
63-
bool analyze(SourceUnit const& _sources);
64-
6562
/// @returns the leftmost identifier in a multi-d IndexAccess.
6663
static Expression const* leftmostBase(IndexAccess const& _indexAccess);
6764

@@ -123,6 +120,8 @@ class SMTEncoder: public ASTConstVisitor
123120
static std::set<SourceUnit const*, ASTNode::CompareByID> sourceDependencies(SourceUnit const& _source);
124121

125122
protected:
123+
void resetSourceAnalysis();
124+
126125
// TODO: Check that we do not have concurrent reads and writes to a variable,
127126
// because the order of expression evaluation is undefined
128127
// TODO: or just force a certain order, but people might have a different idea about that.

libsolidity/formal/SymbolicState.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,8 @@ void SymbolicState::reset()
7878
m_state.reset();
7979
m_tx.reset();
8080
m_crypto.reset();
81-
/// We don't reset m_abi's pointer nor clear m_abiMembers on purpose,
82-
/// since it only helps to keep the already generated types.
83-
solAssert(m_abi, "");
84-
m_abi->reset();
81+
if (m_abi)
82+
m_abi->reset();
8583
}
8684

8785
smtutil::Expression SymbolicState::balances() const
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
==== Source: s1.sol ====
2+
function f() {
3+
ecrecover("1234", 1, "0", abi.decode("", (bytes2)));
4+
}
5+
==== Source: s2.sol ====
6+
contract C {}
7+
// ----
8+
// Warning 6133: (s1.sol:16-67): Statement has no effect.
9+
// Warning 2018: (s1.sol:0-70): Function state mutability can be restricted to pure
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
==== Source: s1.sol ====
2+
function f() {
3+
ecrecover("", 1, "", "");
4+
}
5+
==== Source: s2.sol ====
6+
contract C {}
7+
// ----
8+
// Warning 6133: (s1.sol:16-40): Statement has no effect.
9+
// Warning 2018: (s1.sol:0-43): Function state mutability can be restricted to pure
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
==== Source: l.sol ====
2+
library L {
3+
int constant one = 1;
4+
function f() internal {
5+
one;
6+
}
7+
}
8+
==== Source: s1.sol ====
9+
library L {}
10+
// ----
11+
// Warning 6133: (l.sol:62-65): Statement has no effect.
12+
// Warning 2018: (l.sol:36-69): Function state mutability can be restricted to pure

test/libsolidity/smtCheckerTests/verification_target/simple_assert.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ contract C {
33
}
44
// ====
55
// SMTEngine: all
6+
// SMTIgnoreCex: yes
67
// ----
7-
// Warning 6328: (50-64): CHC: Assertion violation happens here.\nCounterexample:\n\na = 0\n\nTransaction trace:\nC.constructor()\nC.f(0)
8+
// Warning 6328: (50-64): CHC: Assertion violation happens here.

0 commit comments

Comments
 (0)