@@ -43,6 +43,9 @@ ConstraintGraph::~ConstraintGraph() {
4343 delete impl.getGraphNode ();
4444 impl.setGraphNode (nullptr );
4545 }
46+ for (auto *node : FreeList) {
47+ delete node;
48+ }
4649}
4750
4851#pragma mark Graph accessors
@@ -55,11 +58,20 @@ ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
5558 assert (impl.getGraphIndex () < TypeVariables.size () && " Out-of-bounds index" );
5659 assert (TypeVariables[impl.getGraphIndex ()] == typeVar &&
5760 " Type variable mismatch" );
61+ ASSERT (nodePtr->TypeVar == typeVar &&
62+ " Use-after-free" );
5863 return { *nodePtr, impl.getGraphIndex () };
5964 }
6065
6166 // Allocate the new node.
62- auto nodePtr = new ConstraintGraphNode (*this , typeVar);
67+ ConstraintGraphNode *nodePtr;
68+ if (FreeList.empty ())
69+ nodePtr = new ConstraintGraphNode (*this , typeVar);
70+ else {
71+ nodePtr = FreeList.back ();
72+ FreeList.pop_back ();
73+ nodePtr->initTypeVariable (typeVar);
74+ }
6375 unsigned index = TypeVariables.size ();
6476 impl.setGraphNode (nodePtr);
6577 impl.setGraphIndex (index);
@@ -84,6 +96,17 @@ ConstraintGraph::lookupNode(TypeVariableType *typeVar) {
8496 return { *nodePtr, index };
8597}
8698
99+ void ConstraintGraphNode::reset () {
100+ ASSERT (TypeVar);
101+ TypeVar = nullptr ;
102+ Bindings.reset ();
103+ Constraints.clear ();
104+ ConstraintIndex.clear ();
105+ ReferencedBy.clear ();
106+ References.clear ();
107+ EquivalenceClass.clear ();
108+ }
109+
87110bool ConstraintGraphNode::forRepresentativeVar () const {
88111 auto *typeVar = getTypeVariable ();
89112 return typeVar == typeVar->getImpl ().getRepresentative (nullptr );
@@ -422,7 +445,9 @@ void ConstraintGraph::removeNode(TypeVariableType *typeVar) {
422445 // Remove this node.
423446 auto &impl = typeVar->getImpl ();
424447 unsigned index = impl.getGraphIndex ();
425- delete impl.getGraphNode ();
448+ auto *node = impl.getGraphNode ();
449+ node->reset ();
450+ FreeList.push_back (node);
426451 impl.setGraphNode (nullptr );
427452
428453 // Remove this type variable from the list.
0 commit comments