CFGNode stores function definition

This commit is contained in:
wechman 2022-08-30 09:46:55 +02:00
parent 5572d3aed8
commit 6d710920c5
4 changed files with 9 additions and 23 deletions

View File

@ -81,8 +81,8 @@ bool ControlFlowBuilder::visit(BinaryOperation const& _operation)
_operation.leftExpression().accept(*this); _operation.leftExpression().accept(*this);
_operation.rightExpression().accept(*this); _operation.rightExpression().accept(*this);
solAssert(!m_currentNode->resolveFunctionCall(nullptr)); m_currentNode->functionDefinition = _operation.annotation().userDefinedFunction;
m_currentNode->functionCall = _operation.annotation().userDefinedFunction;
auto nextNode = newLabel(); auto nextNode = newLabel();
connect(m_currentNode, nextNode); connect(m_currentNode, nextNode);
@ -102,8 +102,7 @@ bool ControlFlowBuilder::visit(UnaryOperation const& _operation)
if (_operation.annotation().userDefinedFunction) if (_operation.annotation().userDefinedFunction)
{ {
visitNode(_operation); visitNode(_operation);
solAssert(!m_currentNode->resolveFunctionCall(nullptr)); m_currentNode->functionDefinition = _operation.annotation().userDefinedFunction;
m_currentNode->functionCall = _operation.annotation().userDefinedFunction;
auto nextNode = newLabel(); auto nextNode = newLabel();
@ -338,8 +337,7 @@ bool ControlFlowBuilder::visit(FunctionCall const& _functionCall)
_functionCall.expression().accept(*this); _functionCall.expression().accept(*this);
ASTNode::listAccept(_functionCall.arguments(), *this); ASTNode::listAccept(_functionCall.arguments(), *this);
solAssert(!m_currentNode->resolveFunctionCall(nullptr)); m_currentNode->functionDefinition = ASTNode::resolveFunctionCall(_functionCall, m_contract);
m_currentNode->functionCall = &_functionCall;
auto nextNode = newLabel(); auto nextNode = newLabel();

View File

@ -26,13 +26,7 @@ using namespace solidity::util;
using namespace solidity::langutil; using namespace solidity::langutil;
using namespace solidity::frontend; using namespace solidity::frontend;
FunctionDefinition const* CFGNode::resolveFunctionCall(ContractDefinition const* _mostDerivedContract) const
{
return std::visit(GenericVisitor{
[=](FunctionCall const* _call) { return _call ? ASTNode::resolveFunctionCall(*_call, _mostDerivedContract) : nullptr; },
[](FunctionDefinition const* _definition) { return _definition; }
}, functionCall);
}
bool CFG::constructFlow(ASTNode const& _astRoot) bool CFG::constructFlow(ASTNode const& _astRoot)
{ {

View File

@ -99,14 +99,8 @@ struct CFGNode
std::vector<CFGNode*> entries; std::vector<CFGNode*> entries;
/// Exit nodes. All CFG nodes to which control flow may continue after this node. /// Exit nodes. All CFG nodes to which control flow may continue after this node.
std::vector<CFGNode*> exits; std::vector<CFGNode*> exits;
/// Function call done by this node, either a proper function call (allows virtual lookup) /// Function call done by this node
/// or a direct function definition reference (in case of an operator), FunctionDefinition const* functionDefinition;
/// or nullptr.
std::variant<FunctionCall const*, FunctionDefinition const*> functionCall = static_cast<FunctionCall const*>(nullptr);
/// @returns the actual function called given a most derived contract. If no function is called
/// in this node, returns nullptr.
FunctionDefinition const* resolveFunctionCall(ContractDefinition const* _mostDerivedContract) const;
/// Variable occurrences in the node. /// Variable occurrences in the node.
std::vector<VariableOccurrence> variableOccurrences; std::vector<VariableOccurrence> variableOccurrences;
// Source location of this control flow block. // Source location of this control flow block.

View File

@ -81,7 +81,7 @@ void ControlFlowRevertPruner::findRevertStates()
if (_node == functionFlow.exit) if (_node == functionFlow.exit)
foundExit = true; foundExit = true;
auto const* resolvedFunction = _node->resolveFunctionCall(item.contract); auto const* resolvedFunction = _node->functionDefinition;;
if (resolvedFunction && resolvedFunction->isImplemented()) if (resolvedFunction && resolvedFunction->isImplemented())
{ {
CFG::FunctionContractTuple calledFunctionTuple{ CFG::FunctionContractTuple calledFunctionTuple{
@ -131,7 +131,7 @@ void ControlFlowRevertPruner::modifyFunctionFlows()
FunctionFlow const& functionFlow = m_cfg.functionFlow(*item.first.function, item.first.contract); FunctionFlow const& functionFlow = m_cfg.functionFlow(*item.first.function, item.first.contract);
solidity::util::BreadthFirstSearch<CFGNode*>{{functionFlow.entry}}.run( solidity::util::BreadthFirstSearch<CFGNode*>{{functionFlow.entry}}.run(
[&](CFGNode* _node, auto&& _addChild) { [&](CFGNode* _node, auto&& _addChild) {
auto const* resolvedFunction = _node->resolveFunctionCall(item.first.contract); auto const* resolvedFunction = _node->functionDefinition;
if (resolvedFunction && resolvedFunction->isImplemented()) if (resolvedFunction && resolvedFunction->isImplemented())
switch (m_functions.at({findScopeContract(*resolvedFunction, item.first.contract), resolvedFunction})) switch (m_functions.at({findScopeContract(*resolvedFunction, item.first.contract), resolvedFunction}))
{ {