mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
CFGNode stores function definition
This commit is contained in:
parent
5572d3aed8
commit
6d710920c5
@ -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();
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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.
|
||||||
|
@ -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}))
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user