diff options
author | Leonardo Alt <leo@ethereum.org> | 2018-12-14 19:21:43 +0800 |
---|---|---|
committer | Leonardo Alt <leo@ethereum.org> | 2018-12-14 19:21:53 +0800 |
commit | 9199718ec0aa1210094ceb9ca587fe49fba70518 (patch) | |
tree | 483ff6fed2eb914f19710928464a35790a400c60 /libsolidity | |
parent | 6a2809a582d95a5b4cb52abeb3f92ed01857809b (diff) | |
download | dexon-solidity-9199718ec0aa1210094ceb9ca587fe49fba70518.tar.gz dexon-solidity-9199718ec0aa1210094ceb9ca587fe49fba70518.tar.zst dexon-solidity-9199718ec0aa1210094ceb9ca587fe49fba70518.zip |
Clear all mapping knowledge after array variable assignment
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/formal/SMTChecker.cpp | 32 | ||||
-rw-r--r-- | libsolidity/formal/SMTChecker.h | 10 |
2 files changed, 38 insertions, 4 deletions
diff --git a/libsolidity/formal/SMTChecker.cpp b/libsolidity/formal/SMTChecker.cpp index ac24f0a1..bfbd6caf 100644 --- a/libsolidity/formal/SMTChecker.cpp +++ b/libsolidity/formal/SMTChecker.cpp @@ -93,9 +93,10 @@ bool SMTChecker::visit(FunctionDefinition const& _function) m_uninterpretedTerms.clear(); resetStateVariables(); initializeLocalVariables(_function); + m_loopExecutionHappened = false; + m_arrayAssignmentHappened = false; } - m_loopExecutionHappened = false; return true; } @@ -272,7 +273,7 @@ void SMTChecker::endVisit(Assignment const& _assignment) } else if (dynamic_cast<IndexAccess const*>(&_assignment.leftHandSide())) { - arrayAssignment(_assignment); + arrayIndexAssignment(_assignment); defineExpr(_assignment, expr(_assignment.rightHandSide())); } else @@ -463,6 +464,13 @@ void SMTChecker::visitGasLeft(FunctionCall const& _funCall) m_interface->addAssertion(symbolicVar->currentValue() <= symbolicVar->valueAtIndex(index - 1)); } +void SMTChecker::eraseArrayKnowledge() +{ + for (auto const& var: m_variables) + if (var.first->annotation().type->category() == Type::Category::Mapping) + newValue(*var.first); +} + void SMTChecker::inlineFunctionCall(FunctionCall const& _funCall) { FunctionDefinition const* _funDef = nullptr; @@ -678,7 +686,13 @@ void SMTChecker::endVisit(IndexAccess const& _indexAccess) m_uninterpretedTerms.insert(&_indexAccess); } -void SMTChecker::arrayAssignment(Assignment const& _assignment) +void SMTChecker::arrayAssignment() +{ + m_arrayAssignmentHappened = true; + eraseArrayKnowledge(); +} + +void SMTChecker::arrayIndexAssignment(Assignment const& _assignment) { auto const& indexAccess = dynamic_cast<IndexAccess const&>(_assignment.leftHandSide()); if (auto const& id = dynamic_cast<Identifier const*>(&indexAccess.baseExpression())) @@ -869,6 +883,8 @@ void SMTChecker::assignment(VariableDeclaration const& _variable, smt::Expressio checkUnderOverflow(_value, *intType, _location); else if (dynamic_cast<AddressType const*>(type.get())) checkUnderOverflow(_value, IntegerType(160), _location); + else if (dynamic_cast<MappingType const*>(type.get())) + arrayAssignment(); m_interface->addAssertion(newValue(_variable) == _value); } @@ -949,6 +965,12 @@ void SMTChecker::checkCondition( loopComment = "\nNote that some information is erased after the execution of loops.\n" "You can re-introduce information using require()."; + if (m_arrayAssignmentHappened) + loopComment += + "\nNote that array aliasing is not supported," + " therefore all mapping information is erased after" + " a mapping local variable/parameter is assigned.\n" + "You can re-introduce information using require()."; switch (result) { @@ -1082,7 +1104,11 @@ void SMTChecker::initializeFunctionCallParameters(FunctionDefinition const& _fun solAssert(funParams.size() == _callArgs.size(), ""); for (unsigned i = 0; i < funParams.size(); ++i) if (createVariable(*funParams[i])) + { m_interface->addAssertion(_callArgs[i] == newValue(*funParams[i])); + if (funParams[i]->annotation().type->category() == Type::Category::Mapping) + m_arrayAssignmentHappened = true; + } for (auto const& variable: _function.localVariables()) if (createVariable(*variable)) diff --git a/libsolidity/formal/SMTChecker.h b/libsolidity/formal/SMTChecker.h index 4743a76a..c749cbc3 100644 --- a/libsolidity/formal/SMTChecker.h +++ b/libsolidity/formal/SMTChecker.h @@ -97,7 +97,14 @@ private: void defineGlobalVariable(std::string const& _name, Expression const& _expr, bool _increaseIndex = false); void defineGlobalFunction(std::string const& _name, Expression const& _expr); - void arrayAssignment(Assignment const& _assignment); + /// Handles the side effects of assignment + /// to variable of some SMT array type + /// while aliasing is not supported. + void arrayAssignment(); + /// Handles assignment to SMT array index. + void arrayIndexAssignment(Assignment const& _assignment); + /// Erases information about SMT arrays. + void eraseArrayKnowledge(); /// Division expression in the given type. Requires special treatment because /// of rounding for signed division. @@ -205,6 +212,7 @@ private: std::shared_ptr<smt::SolverInterface> m_interface; std::shared_ptr<VariableUsage> m_variableUsage; bool m_loopExecutionHappened = false; + bool m_arrayAssignmentHappened = false; /// An Expression may have multiple smt::Expression due to /// repeated calls to the same function. std::unordered_map<Expression const*, std::shared_ptr<SymbolicVariable>> m_expressions; |