MCPcopy Create free account
hub / github.com/argotorg/solidity / markRecursiveCalls

Function markRecursiveCalls

libyul/backends/evm/ControlFlowGraphBuilder.cpp:103–148  ·  view source on GitHub ↗

Sets the ``recursive`` member to ``true`` for all recursive function calls.

Source from the content-addressed store, hash-verified

101
102/// Sets the ``recursive`` member to ``true`` for all recursive function calls.
103void markRecursiveCalls(CFG& _cfg)
104{
105 std::map<CFG::BasicBlock*, std::vector<CFG::FunctionCall*>> callsPerBlock;
106 auto const& findCalls = [&](CFG::BasicBlock* _block)
107 {
108 if (auto* calls = util::valueOrNullptr(callsPerBlock, _block))
109 return *calls;
110 std::vector<CFG::FunctionCall*>& calls = callsPerBlock[_block];
111 util::BreadthFirstSearch<CFG::BasicBlock*>{{_block}}.run([&](CFG::BasicBlock* _block, auto _addChild) {
112 for (auto& operation: _block->operations)
113 if (auto* functionCall = std::get_if<CFG::FunctionCall>(&operation.operation))
114 calls.emplace_back(functionCall);
115 std::visit(util::GenericVisitor{
116 [&](CFG::BasicBlock::MainExit const&) {},
117 [&](CFG::BasicBlock::Jump const& _jump)
118 {
119 _addChild(_jump.target);
120 },
121 [&](CFG::BasicBlock::ConditionalJump const& _conditionalJump)
122 {
123 _addChild(_conditionalJump.zero);
124 _addChild(_conditionalJump.nonZero);
125 },
126 [&](CFG::BasicBlock::FunctionReturn const&) {},
127 [&](CFG::BasicBlock::Terminated const&) {},
128 }, _block->exit);
129 });
130 return calls;
131 };
132 for (auto& functionInfo: _cfg.functionInfo | ranges::views::values)
133 for (CFG::FunctionCall* call: findCalls(functionInfo.entry))
134 {
135 util::BreadthFirstSearch<CFG::FunctionCall*> breadthFirstSearch{{call}};
136 breadthFirstSearch.run([&](CFG::FunctionCall* _call, auto _addChild) {
137 auto& calledFunctionInfo = _cfg.functionInfo.at(&_call->function.get());
138 if (&calledFunctionInfo == &functionInfo)
139 {
140 call->recursive = true;
141 breadthFirstSearch.abort();
142 return;
143 }
144 for (CFG::FunctionCall* nestedCall: findCalls(_cfg.functionInfo.at(&_call->function.get()).entry))
145 _addChild(nestedCall);
146 });
147 }
148}
149
150/// Marks each cut-vertex in the CFG, i.e. each block that begins a disconnected sub-graph of the CFG.
151/// Entering such a block means that control flow will never return to a previously visited block.

Callers 1

buildMethod · 0.85

Calls 5

valueOrNullptrFunction · 0.85
atMethod · 0.80
abortMethod · 0.80
runMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected