mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Take inlined function calls into account when collecting touched variables
This commit is contained in:
parent
6f9b69ebc3
commit
1d63b97857
@ -7,6 +7,7 @@ Compiler Features:
|
|||||||
|
|
||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
* SMTChecker: SSA control-flow did not take into account state variables that were modified inside inlined functions that were called inside branches.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include <libsolidity/formal/VariableUsage.h>
|
#include <libsolidity/formal/VariableUsage.h>
|
||||||
|
|
||||||
|
#include <libsolidity/formal/SMTChecker.h>
|
||||||
|
|
||||||
#include <libsolidity/ast/ASTVisitor.h>
|
#include <libsolidity/ast/ASTVisitor.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -27,17 +29,19 @@ VariableUsage::VariableUsage(ASTNode const& _node)
|
|||||||
{
|
{
|
||||||
auto nodeFun = [&](ASTNode const& n) -> bool
|
auto nodeFun = [&](ASTNode const& n) -> bool
|
||||||
{
|
{
|
||||||
if (Identifier const* identifier = dynamic_cast<decltype(identifier)>(&n))
|
if (auto identifier = dynamic_cast<Identifier const*>(&n))
|
||||||
{
|
{
|
||||||
Declaration const* declaration = identifier->annotation().referencedDeclaration;
|
Declaration const* declaration = identifier->annotation().referencedDeclaration;
|
||||||
solAssert(declaration, "");
|
solAssert(declaration, "");
|
||||||
if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))
|
if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||||
if (
|
if (identifier->annotation().lValueRequested)
|
||||||
identifier->annotation().lValueRequested &&
|
|
||||||
varDecl->annotation().type->isValueType()
|
|
||||||
)
|
|
||||||
m_touchedVariable[&n] = varDecl;
|
m_touchedVariable[&n] = varDecl;
|
||||||
}
|
}
|
||||||
|
else if (auto funCall = dynamic_cast<FunctionCall const*>(&n))
|
||||||
|
{
|
||||||
|
if (FunctionDefinition const* funDef = SMTChecker::inlinedFunctionCallToDefinition(*funCall))
|
||||||
|
m_children[&n].push_back(funDef);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
auto edgeFun = [&](ASTNode const& _parent, ASTNode const& _child)
|
auto edgeFun = [&](ASTNode const& _parent, ASTNode const& _child)
|
||||||
@ -56,6 +60,7 @@ vector<VariableDeclaration const*> VariableUsage::touchedVariables(ASTNode const
|
|||||||
return {};
|
return {};
|
||||||
|
|
||||||
set<VariableDeclaration const*> touched;
|
set<VariableDeclaration const*> touched;
|
||||||
|
set<ASTNode const*> visitedFunctions;
|
||||||
vector<ASTNode const*> toVisit;
|
vector<ASTNode const*> toVisit;
|
||||||
toVisit.push_back(&_node);
|
toVisit.push_back(&_node);
|
||||||
|
|
||||||
@ -63,10 +68,16 @@ vector<VariableDeclaration const*> VariableUsage::touchedVariables(ASTNode const
|
|||||||
{
|
{
|
||||||
ASTNode const* n = toVisit.back();
|
ASTNode const* n = toVisit.back();
|
||||||
toVisit.pop_back();
|
toVisit.pop_back();
|
||||||
|
|
||||||
|
if (auto funDef = dynamic_cast<FunctionDefinition const*>(n))
|
||||||
|
visitedFunctions.insert(funDef);
|
||||||
|
|
||||||
if (m_children.count(n))
|
if (m_children.count(n))
|
||||||
{
|
{
|
||||||
solAssert(!m_touchedVariable.count(n), "");
|
solAssert(!m_touchedVariable.count(n), "");
|
||||||
toVisit += m_children.at(n);
|
for (auto const& child: m_children.at(n))
|
||||||
|
if (!visitedFunctions.count(child))
|
||||||
|
toVisit.push_back(child);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user