52 lines
1.6 KiB
Diff
52 lines
1.6 KiB
Diff
# UNDF: UNDF-2026-000000288
|
|
diff --git a/libyul/optimiser/CallGraphGenerator.cpp b/libyul/optimiser/CallGraphGenerator.cpp
|
|
index b8cb7c3..patched 100644
|
|
--- a/libyul/optimiser/CallGraphGenerator.cpp
|
|
+++ b/libyul/optimiser/CallGraphGenerator.cpp
|
|
@@ -28,6 +28,7 @@
|
|
#include <libsolutil/CommonData.h>
|
|
#include <libsolutil/Visitor.h>
|
|
|
|
+#include <unordered_set>
|
|
#include <stack>
|
|
|
|
using namespace solidity;
|
|
@@ -37,12 +38,16 @@ namespace
|
|
{
|
|
// TODO: This algorithm is non-optimal.
|
|
struct CallGraphCycleFinder
|
|
{
|
|
CallGraph const& callGraph;
|
|
std::set<FunctionHandle> containedInCycle{};
|
|
std::set<FunctionHandle> visited{};
|
|
std::vector<FunctionHandle> currentPath{};
|
|
+ std::set<FunctionHandle> currentPathSet{};
|
|
|
|
void visit(FunctionHandle const& _function)
|
|
{
|
|
if (visited.count(_function))
|
|
return;
|
|
- if (
|
|
- auto it = find(currentPath.begin(), currentPath.end(), _function);
|
|
- it != currentPath.end()
|
|
- )
|
|
- containedInCycle.insert(it, currentPath.end());
|
|
+ if (currentPathSet.count(_function))
|
|
+ {
|
|
+ // Function is already in the current DFS path — it is part of a cycle.
|
|
+ // Walk currentPath to find where the cycle begins and collect all members.
|
|
+ auto it = find(currentPath.begin(), currentPath.end(), _function);
|
|
+ containedInCycle.insert(it, currentPath.end());
|
|
+ }
|
|
else
|
|
{
|
|
currentPath.emplace_back(_function);
|
|
+ currentPathSet.insert(_function);
|
|
if (callGraph.functionCalls.count(_function))
|
|
for (auto const& child: callGraph.functionCalls.at(_function))
|
|
visit(child);
|
|
currentPath.pop_back();
|
|
+ currentPathSet.erase(_function);
|
|
visited.insert(_function);
|
|
}
|
|
}
|