summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndres Noetzli <andres.noetzli@gmail.com>2019-03-28 21:02:37 -0700
committerAndrew Reynolds <andrew.j.reynolds@gmail.com>2019-03-28 23:02:37 -0500
commita1decafaf4c7c46a4eda3d816e9a8799b4c96ad3 (patch)
tree72ea26e545fd904738158c326f2c78c152479d2a /src
parent952ee3698e7760ccbd90fac5691d455d807af3a6 (diff)
Fix freeing nodes with maxed refcounts (#2903)
Diffstat (limited to 'src')
-rw-r--r--src/expr/node_manager.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/expr/node_manager.cpp b/src/expr/node_manager.cpp
index c9d772b26..66d597a36 100644
--- a/src/expr/node_manager.cpp
+++ b/src/expr/node_manager.cpp
@@ -363,7 +363,10 @@ void NodeManager::reclaimZombies() {
std::vector<NodeValue*> NodeManager::TopologicalSort(
const std::vector<NodeValue*>& roots) {
std::vector<NodeValue*> order;
+ // The stack of nodes to visit. The Boolean value is false when visiting the
+ // node in preorder and true when visiting it in postorder.
std::vector<std::pair<bool, NodeValue*> > stack;
+ // Nodes that have been visited in both pre- and postorder
NodeValueIDSet visited;
const NodeValueIDSet root_set(roots.begin(), roots.end());
@@ -382,17 +385,20 @@ std::vector<NodeValue*> NodeManager::TopologicalSort(
order.push_back(current);
}
stack.pop_back();
- } else {
+ }
+ else if (visited.find(current) == visited.end())
+ {
stack.back().first = true;
- Assert(visited.count(current) == 0);
visited.insert(current);
for (unsigned i = 0; i < current->getNumChildren(); ++i) {
expr::NodeValue* child = current->getChild(i);
- if (visited.find(child) == visited.end()) {
- stack.push_back(std::make_pair(false, child));
- }
+ stack.push_back(std::make_pair(false, child));
}
}
+ else
+ {
+ stack.pop_back();
+ }
}
}
Assert(order.size() == roots.size());
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback