mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Basic support to free constants
This commit is contained in:
parent
6ae82fcec2
commit
095d337140
@ -61,8 +61,6 @@ BMC::BMC(
|
|||||||
|
|
||||||
void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<VerificationTargetType>> _solvedTargets)
|
void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<VerificationTargetType>> _solvedTargets)
|
||||||
{
|
{
|
||||||
/// This is currently used to abort analysis of SourceUnits
|
|
||||||
/// containing file level functions or constants.
|
|
||||||
if (SMTEncoder::analyze(_source))
|
if (SMTEncoder::analyze(_source))
|
||||||
{
|
{
|
||||||
m_solvedTargets = move(_solvedTargets);
|
m_solvedTargets = move(_solvedTargets);
|
||||||
@ -70,6 +68,7 @@ void BMC::analyze(SourceUnit const& _source, map<ASTNode const*, set<Verificatio
|
|||||||
m_context.clear();
|
m_context.clear();
|
||||||
m_context.setAssertionAccumulation(true);
|
m_context.setAssertionAccumulation(true);
|
||||||
m_variableUsage.setFunctionInlining(shouldInlineFunctionCall);
|
m_variableUsage.setFunctionInlining(shouldInlineFunctionCall);
|
||||||
|
createFreeConstants(sourceDependencies(_source));
|
||||||
|
|
||||||
_source.accept(*this);
|
_source.accept(*this);
|
||||||
}
|
}
|
||||||
|
@ -76,17 +76,13 @@ CHC::CHC(
|
|||||||
|
|
||||||
void CHC::analyze(SourceUnit const& _source)
|
void CHC::analyze(SourceUnit const& _source)
|
||||||
{
|
{
|
||||||
/// This is currently used to abort analysis of SourceUnits
|
|
||||||
/// containing file level functions or constants.
|
|
||||||
if (SMTEncoder::analyze(_source))
|
if (SMTEncoder::analyze(_source))
|
||||||
{
|
{
|
||||||
resetSourceAnalysis();
|
resetSourceAnalysis();
|
||||||
|
|
||||||
set<SourceUnit const*, ASTNode::CompareByID> sources;
|
auto sources = sourceDependencies(_source);
|
||||||
sources.insert(&_source);
|
|
||||||
for (auto const& source: _source.referencedSourceUnits(true))
|
|
||||||
sources.insert(source);
|
|
||||||
collectFreeFunctions(sources);
|
collectFreeFunctions(sources);
|
||||||
|
createFreeConstants(sources);
|
||||||
for (auto const* source: sources)
|
for (auto const* source: sources)
|
||||||
defineInterfacesAndSummaries(*source);
|
defineInterfacesAndSummaries(*source);
|
||||||
for (auto const* source: sources)
|
for (auto const* source: sources)
|
||||||
@ -1422,7 +1418,8 @@ void CHC::verificationTargetEncountered(
|
|||||||
if (!m_settings.targets.has(_type))
|
if (!m_settings.targets.has(_type))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
solAssert(m_currentContract || m_currentFunction, "");
|
if (!(m_currentContract || m_currentFunction))
|
||||||
|
return;
|
||||||
|
|
||||||
bool scopeIsFunction = m_currentFunction && !m_currentFunction->isConstructor();
|
bool scopeIsFunction = m_currentFunction && !m_currentFunction->isConstructor();
|
||||||
auto errorId = newErrorId();
|
auto errorId = newErrorId();
|
||||||
|
@ -51,27 +51,6 @@ SMTEncoder::SMTEncoder(smt::EncodingContext& _context):
|
|||||||
|
|
||||||
bool SMTEncoder::analyze(SourceUnit const& _source)
|
bool SMTEncoder::analyze(SourceUnit const& _source)
|
||||||
{
|
{
|
||||||
set<SourceUnit const*, smt::EncodingContext::IdCompare> sources;
|
|
||||||
sources.insert(&_source);
|
|
||||||
for (auto const& source: _source.referencedSourceUnits(true))
|
|
||||||
sources.insert(source);
|
|
||||||
|
|
||||||
bool analysis = true;
|
|
||||||
for (auto source: sources)
|
|
||||||
for (auto node: source->nodes())
|
|
||||||
if (auto var = dynamic_pointer_cast<VariableDeclaration>(node))
|
|
||||||
{
|
|
||||||
m_errorReporter.warning(
|
|
||||||
8195_error,
|
|
||||||
var->location(),
|
|
||||||
"Model checker analysis was not possible because file level constants are not supported."
|
|
||||||
);
|
|
||||||
analysis = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!analysis)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
state().prepareForSourceUnit(_source);
|
state().prepareForSourceUnit(_source);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -437,14 +416,9 @@ void SMTEncoder::endVisit(TupleExpression const& _tuple)
|
|||||||
auto values = applyMap(_tuple.components(), [this](auto const& component) -> optional<smtutil::Expression> {
|
auto values = applyMap(_tuple.components(), [this](auto const& component) -> optional<smtutil::Expression> {
|
||||||
if (component)
|
if (component)
|
||||||
{
|
{
|
||||||
if (auto varDecl = identifierToVariable(*component))
|
if (!m_context.knownExpression(*component))
|
||||||
return currentValue(*varDecl);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!m_context.knownExpression(*component))
|
|
||||||
createExpr(*component);
|
createExpr(*component);
|
||||||
return expr(*component);
|
return expr(*component);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
@ -1395,6 +1369,9 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess)
|
|||||||
auto varDecl = identifierToVariable(*id);
|
auto varDecl = identifierToVariable(*id);
|
||||||
solAssert(varDecl, "");
|
solAssert(varDecl, "");
|
||||||
array = m_context.variable(*varDecl);
|
array = m_context.variable(*varDecl);
|
||||||
|
|
||||||
|
if (varDecl && varDecl->isConstant())
|
||||||
|
m_context.addAssertion(currentValue(*varDecl) == expr(*id));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2599,6 +2576,7 @@ VariableDeclaration const* SMTEncoder::identifierToVariable(Expression const& _e
|
|||||||
solAssert(m_context.knownVariable(*varDecl), "");
|
solAssert(m_context.knownVariable(*varDecl), "");
|
||||||
return varDecl;
|
return varDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2913,6 +2891,15 @@ set<FunctionCall const*> SMTEncoder::collectABICalls(ASTNode const* _node)
|
|||||||
return ABIFunctions(_node).abiCalls;
|
return ABIFunctions(_node).abiCalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set<SourceUnit const*, ASTNode::CompareByID> SMTEncoder::sourceDependencies(SourceUnit const& _source)
|
||||||
|
{
|
||||||
|
set<SourceUnit const*, ASTNode::CompareByID> sources;
|
||||||
|
sources.insert(&_source);
|
||||||
|
for (auto const& source: _source.referencedSourceUnits(true))
|
||||||
|
sources.insert(source);
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
|
||||||
void SMTEncoder::createReturnedExpressions(FunctionCall const& _funCall, ContractDefinition const* _contextContract)
|
void SMTEncoder::createReturnedExpressions(FunctionCall const& _funCall, ContractDefinition const* _contextContract)
|
||||||
{
|
{
|
||||||
auto funDef = functionCallToDefinition(_funCall, currentScopeContract(), _contextContract);
|
auto funDef = functionCallToDefinition(_funCall, currentScopeContract(), _contextContract);
|
||||||
@ -2978,6 +2965,14 @@ void SMTEncoder::collectFreeFunctions(set<SourceUnit const*, ASTNode::CompareByI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SMTEncoder::createFreeConstants(set<SourceUnit const*, ASTNode::CompareByID> const& _sources)
|
||||||
|
{
|
||||||
|
for (auto source: _sources)
|
||||||
|
for (auto node: source->nodes())
|
||||||
|
if (auto var = dynamic_cast<VariableDeclaration const*>(node.get()))
|
||||||
|
createVariable(*var);
|
||||||
|
}
|
||||||
|
|
||||||
smt::SymbolicState& SMTEncoder::state()
|
smt::SymbolicState& SMTEncoder::state()
|
||||||
{
|
{
|
||||||
return m_context.state();
|
return m_context.state();
|
||||||
|
@ -112,6 +112,10 @@ public:
|
|||||||
|
|
||||||
static std::set<FunctionCall const*> collectABICalls(ASTNode const* _node);
|
static std::set<FunctionCall const*> collectABICalls(ASTNode const* _node);
|
||||||
|
|
||||||
|
/// @returns all the sources that @param _source depends on,
|
||||||
|
/// including itself.
|
||||||
|
static std::set<SourceUnit const*, ASTNode::CompareByID> sourceDependencies(SourceUnit const& _source);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// TODO: Check that we do not have concurrent reads and writes to a variable,
|
// TODO: Check that we do not have concurrent reads and writes to a variable,
|
||||||
// because the order of expression evaluation is undefined
|
// because the order of expression evaluation is undefined
|
||||||
@ -373,6 +377,8 @@ protected:
|
|||||||
/// and internal library functions in m_freeFunctions.
|
/// and internal library functions in m_freeFunctions.
|
||||||
void collectFreeFunctions(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources);
|
void collectFreeFunctions(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources);
|
||||||
std::set<FunctionDefinition const*, ASTNode::CompareByID> const& allFreeFunctions() const { return m_freeFunctions; }
|
std::set<FunctionDefinition const*, ASTNode::CompareByID> const& allFreeFunctions() const { return m_freeFunctions; }
|
||||||
|
/// Create symbolic variables for the free constants in all @param _sources.
|
||||||
|
void createFreeConstants(std::set<SourceUnit const*, ASTNode::CompareByID> const& _sources);
|
||||||
|
|
||||||
/// @returns a note to be added to warnings.
|
/// @returns a note to be added to warnings.
|
||||||
std::string extraComment();
|
std::string extraComment();
|
||||||
|
@ -7,5 +7,4 @@ contract C {
|
|||||||
// ====
|
// ====
|
||||||
// SMTEngine: all
|
// SMTEngine: all
|
||||||
// ----
|
// ----
|
||||||
// Warning 8195: (0-20): Model checker analysis was not possible because file level constants are not supported.
|
// Warning 4984: (125-130): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\n\nx = 115792089237316195423570985008687907853269984665640564039457584007913129639894\n = 0\n\nTransaction trace:\nC.constructor()\nC.f(115792089237316195423570985008687907853269984665640564039457584007913129639894)
|
||||||
// Warning 8195: (0-20): Model checker analysis was not possible because file level constants are not supported.
|
|
||||||
|
@ -10,10 +10,4 @@ contract C {
|
|||||||
// ====
|
// ====
|
||||||
// SMTEngine: all
|
// SMTEngine: all
|
||||||
// ----
|
// ----
|
||||||
// Warning 2018: (188-278): Function state mutability can be restricted to pure
|
// Warning 2018: (220-310): Function state mutability can be restricted to pure
|
||||||
// Warning 8195: (0-23): Model checker analysis was not possible because file level constants are not supported.
|
|
||||||
// Warning 8195: (79-133): Model checker analysis was not possible because file level constants are not supported.
|
|
||||||
// Warning 8195: (135-172): Model checker analysis was not possible because file level constants are not supported.
|
|
||||||
// Warning 8195: (0-23): Model checker analysis was not possible because file level constants are not supported.
|
|
||||||
// Warning 8195: (79-133): Model checker analysis was not possible because file level constants are not supported.
|
|
||||||
// Warning 8195: (135-172): Model checker analysis was not possible because file level constants are not supported.
|
|
||||||
|
@ -12,5 +12,6 @@ function fun(uint[] calldata _x, uint[] storage _y) view returns (uint, uint[]
|
|||||||
// ====
|
// ====
|
||||||
// SMTEngine: all
|
// SMTEngine: all
|
||||||
// ----
|
// ----
|
||||||
// Warning 8195: (32-52): Model checker analysis was not possible because file level constants are not supported.
|
// Warning 4984: (222-234): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\ndata = []\nx = 1\n = 0\n = 0\na = 0\n\nTransaction trace:\nC.constructor()\nState: data = []\nC.f(1, input)\n ::fun(_x, []) -- internal call
|
||||||
// Warning 8195: (32-52): Model checker analysis was not possible because file level constants are not supported.
|
// Warning 4984: (222-238): CHC: Overflow (resulting value larger than 2**256 - 1) happens here.\nCounterexample:\ndata = []\nx = 115792089237316195423570985008687907853269984665640564039457584007913129632175\n = 0\n = 0\na = 0\n\nTransaction trace:\nC.constructor()\nState: data = []\nC.f(115792089237316195423570985008687907853269984665640564039457584007913129632175, input)\n ::fun(_x, []) -- internal call
|
||||||
|
// Warning 6368: (347-352): CHC: Out of bounds access happens here.\nCounterexample:\ndata = []\nx = 0\ninput = [5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 14, 5, 5, 5, 5, 5, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5]\n = 0\n = 0\n\nTransaction trace:\nC.constructor()\nState: data = []\nC.f(0, [5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 14, 5, 5, 5, 5, 5, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5])\n ::fun([5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 14, 5, 5, 5, 5, 5, 19, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5], []) -- internal call
|
||||||
|
Loading…
Reference in New Issue
Block a user