Modify std::multimap in V3Combine safely.
We used to iterate the m_callMmap std::multimap by getting limit iterators from equal_range, but we also modify the same map in the loop which invalidates those limit iterators. Note this only caused actual problems if the new AstCCall inserted via 'addCall' in the loop had a memory address (which is used as the key) which fell into the range returned by equal_range, so was pretty hard to trigger.
This commit is contained in:
parent
546ccd56c4
commit
6a54fb6f96
|
|
@ -86,11 +86,10 @@ public:
|
|||
} else {
|
||||
UINFO(4, " Remove " << oldfuncp << endl);
|
||||
}
|
||||
std::pair<CallMmap::iterator, CallMmap::iterator> eqrange
|
||||
= m_callMmap.equal_range(oldfuncp);
|
||||
for (CallMmap::iterator nextit = eqrange.first; nextit != eqrange.second;) {
|
||||
CallMmap::iterator eqit = nextit++;
|
||||
AstCCall* callp = eqit->second;
|
||||
// Note: m_callMmap modified in loop, so not using equal_range.
|
||||
for (CallMmap::iterator it = m_callMmap.find(oldfuncp); it != m_callMmap.end();
|
||||
it = m_callMmap.find(oldfuncp)) {
|
||||
AstCCall* callp = it->second;
|
||||
if (!callp->user3()) { // !already done
|
||||
UINFO(4, " Called " << callp << endl);
|
||||
UASSERT_OBJ(callp->funcp() == oldfuncp, callp,
|
||||
|
|
@ -105,8 +104,13 @@ public:
|
|||
}
|
||||
callp->user3(true); // Dead now
|
||||
VL_DO_DANGLING(pushDeletep(callp), callp);
|
||||
m_callMmap.erase(eqit); // Fix the table
|
||||
}
|
||||
// It is safe to unconditionally remove this entry here as the above
|
||||
// 'if' would never be entered again for this entry (we set user3).
|
||||
// The only other place where m_callMmap is looked up is deleteCall
|
||||
// below, but that is only ever called straight after an addCall
|
||||
// of the node being deleted, so it won't miss this entry.
|
||||
m_callMmap.erase(it); // Fix the table
|
||||
}
|
||||
}
|
||||
// METHODS
|
||||
|
|
|
|||
Loading…
Reference in New Issue