mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
[SMTChecker] Fix ICE in branch-inline function call-modify local variable
This commit is contained in:
@@ -31,26 +31,30 @@ void VariableUsage::endVisit(Identifier const& _identifier)
|
||||
solAssert(declaration, "");
|
||||
if (VariableDeclaration const* varDecl = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||
if (_identifier.annotation().lValueRequested)
|
||||
m_touchedVariables.insert(varDecl);
|
||||
{
|
||||
solAssert(m_lastCall, "");
|
||||
if (!varDecl->isLocalVariable() || varDecl->functionOrModifierDefinition() == m_lastCall)
|
||||
m_touchedVariables.insert(varDecl);
|
||||
}
|
||||
}
|
||||
|
||||
void VariableUsage::endVisit(FunctionCall const& _funCall)
|
||||
{
|
||||
if (auto const& funDef = SMTChecker::inlinedFunctionCallToDefinition(_funCall))
|
||||
if (find(m_functionPath.begin(), m_functionPath.end(), funDef) == m_functionPath.end())
|
||||
if (find(m_callStack.begin(), m_callStack.end(), funDef) == m_callStack.end())
|
||||
funDef->accept(*this);
|
||||
}
|
||||
|
||||
bool VariableUsage::visit(FunctionDefinition const& _function)
|
||||
{
|
||||
m_functionPath.push_back(&_function);
|
||||
m_callStack.push_back(&_function);
|
||||
return true;
|
||||
}
|
||||
|
||||
void VariableUsage::endVisit(FunctionDefinition const&)
|
||||
{
|
||||
solAssert(!m_functionPath.empty(), "");
|
||||
m_functionPath.pop_back();
|
||||
solAssert(!m_callStack.empty(), "");
|
||||
m_callStack.pop_back();
|
||||
}
|
||||
|
||||
void VariableUsage::endVisit(ModifierInvocation const& _modifierInv)
|
||||
@@ -62,18 +66,21 @@ void VariableUsage::endVisit(ModifierInvocation const& _modifierInv)
|
||||
|
||||
void VariableUsage::endVisit(PlaceholderStatement const&)
|
||||
{
|
||||
solAssert(!m_functionPath.empty(), "");
|
||||
FunctionDefinition const* function = m_functionPath.back();
|
||||
solAssert(function, "");
|
||||
if (function->isImplemented())
|
||||
function->body().accept(*this);
|
||||
solAssert(!m_callStack.empty(), "");
|
||||
FunctionDefinition const* funDef = nullptr;
|
||||
for (auto it = m_callStack.rbegin(); it != m_callStack.rend() && !funDef; ++it)
|
||||
funDef = dynamic_cast<FunctionDefinition const*>(*it);
|
||||
solAssert(funDef, "");
|
||||
if (funDef->isImplemented())
|
||||
funDef->body().accept(*this);
|
||||
}
|
||||
|
||||
set<VariableDeclaration const*> VariableUsage::touchedVariables(ASTNode const& _node, vector<FunctionDefinition const*> const& _outerCallstack)
|
||||
set<VariableDeclaration const*> VariableUsage::touchedVariables(ASTNode const& _node, vector<CallableDeclaration const*> const& _outerCallstack)
|
||||
{
|
||||
m_touchedVariables.clear();
|
||||
m_functionPath.clear();
|
||||
m_functionPath += _outerCallstack;
|
||||
m_callStack.clear();
|
||||
m_callStack += _outerCallstack;
|
||||
m_lastCall = m_callStack.back();
|
||||
_node.accept(*this);
|
||||
return m_touchedVariables;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user