mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
fixup! Imp
This commit is contained in:
parent
1bfc766139
commit
3838a3a29f
@ -17,6 +17,7 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
#include <libsolidity/analysis/FunctionCallGraph.h>
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace solidity::frontend;
|
||||
@ -45,46 +46,59 @@ bool FunctionCallGraphBuilder::CompareByID::operator()(int64_t _lhs, Node const&
|
||||
return _lhs < std::get<ASTNode const*>(_rhs)->id();
|
||||
}
|
||||
|
||||
shared_ptr<FunctionCallGraphBuilder::ContractCallGraph> FunctionCallGraphBuilder::create(ContractDefinition const& _contract)
|
||||
unique_ptr<FunctionCallGraphBuilder::ContractCallGraph> FunctionCallGraphBuilder::create(ContractDefinition const& _contract)
|
||||
{
|
||||
m_contract = &_contract;
|
||||
FunctionCallGraphBuilder builder;
|
||||
|
||||
m_graph = make_shared<ContractCallGraph>(_contract);
|
||||
builder.m_contract = &_contract;
|
||||
|
||||
builder.m_graph = make_unique<ContractCallGraph>(_contract);
|
||||
|
||||
// Create graph for constructor, state vars, etc
|
||||
m_currentNode = SpecialNode::EntryCreation;
|
||||
m_currentDispatch = SpecialNode::InternalCreationDispatch;
|
||||
for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts)
|
||||
visitConstructor(*contract);
|
||||
builder.m_currentNode = SpecialNode::EntryCreation;
|
||||
builder.m_currentDispatch = SpecialNode::InternalCreationDispatch;
|
||||
|
||||
m_currentNode.reset();
|
||||
m_currentDispatch = SpecialNode::InternalDispatch;
|
||||
for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts | boost::adaptors::reversed)
|
||||
{
|
||||
for (auto const* stateVar: contract->stateVariables())
|
||||
stateVar->accept(builder);
|
||||
|
||||
for (auto arg: contract->baseContracts())
|
||||
arg->accept(builder);
|
||||
|
||||
if (contract->constructor())
|
||||
{
|
||||
builder.add(*builder.m_currentNode, contract->constructor());
|
||||
contract->constructor()->accept(builder);
|
||||
builder.m_currentNode = contract->constructor();
|
||||
}
|
||||
}
|
||||
|
||||
builder.m_currentNode.reset();
|
||||
builder.m_currentDispatch = SpecialNode::InternalDispatch;
|
||||
|
||||
// Create graph for all publicly reachable functions
|
||||
for (auto& [hash, functionType]: _contract.interfaceFunctionList())
|
||||
{
|
||||
(void)hash;
|
||||
if (auto const* funcDef = dynamic_cast<FunctionDefinition const*>(&functionType->declaration()))
|
||||
if (!m_graph->edges.count(funcDef))
|
||||
visitCallable(funcDef);
|
||||
if (!builder.m_graph->edges.count(funcDef))
|
||||
builder.visitCallable(funcDef);
|
||||
|
||||
// Add all external functions to the RuntimeDispatch
|
||||
add(SpecialNode::Entry, &functionType->declaration());
|
||||
builder.add(SpecialNode::Entry, &functionType->declaration());
|
||||
}
|
||||
|
||||
// Add all InternalCreationDispatch calls to the RuntimeDispatch as well
|
||||
add(SpecialNode::InternalDispatch, SpecialNode::InternalCreationDispatch);
|
||||
builder.add(SpecialNode::InternalDispatch, SpecialNode::InternalCreationDispatch);
|
||||
|
||||
if (_contract.fallbackFunction())
|
||||
add(SpecialNode::Entry, _contract.fallbackFunction());
|
||||
builder.add(SpecialNode::Entry, _contract.fallbackFunction());
|
||||
|
||||
if (_contract.receiveFunction())
|
||||
add(SpecialNode::Entry, _contract.receiveFunction());
|
||||
builder.add(SpecialNode::Entry, _contract.receiveFunction());
|
||||
|
||||
m_contract = nullptr;
|
||||
solAssert(!m_currentNode.has_value(), "Current node not properly reset.");
|
||||
|
||||
return m_graph;
|
||||
return std::move(builder.m_graph);
|
||||
}
|
||||
|
||||
bool FunctionCallGraphBuilder::visit(Identifier const& _identifier)
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
std::set<ContractDefinition const*, ASTNode::CompareByID> createdContracts;
|
||||
};
|
||||
|
||||
std::shared_ptr<ContractCallGraph> create(ContractDefinition const& _contract);
|
||||
static std::unique_ptr<ContractCallGraph> create(ContractDefinition const& _contract);
|
||||
|
||||
private:
|
||||
bool visit(Identifier const& _identifier) override;
|
||||
@ -91,7 +91,7 @@ private:
|
||||
|
||||
ContractDefinition const* m_contract = nullptr;
|
||||
std::optional<Node> m_currentNode;
|
||||
std::shared_ptr<ContractCallGraph> m_graph = nullptr;
|
||||
std::unique_ptr<ContractCallGraph> m_graph = nullptr;
|
||||
Node m_currentDispatch = SpecialNode::InternalCreationDispatch;
|
||||
};
|
||||
|
||||
|
@ -402,12 +402,11 @@ bool CompilerStack::analyze()
|
||||
|
||||
if (noErrors)
|
||||
{
|
||||
FunctionCallGraphBuilder builder;
|
||||
for (Source const* source: m_sourceOrder)
|
||||
if (source->ast)
|
||||
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
m_contractCallGraphs.emplace(contract, builder.create(*contract));
|
||||
m_contractCallGraphs.emplace(contract, FunctionCallGraphBuilder::create(*contract));
|
||||
}
|
||||
|
||||
if (noErrors)
|
||||
|
Loading…
Reference in New Issue
Block a user