Skip to content

Commit 71289ad

Browse files
authored
Merge pull request #8102 from The-OpenROAD-Project-staging/secure-merge_net-fix
odb, rsz: Fixed incorrect BTerm iteration in mergeNet(). Changed a wrong code sequence in removeBuffer().
2 parents 795d8a4 + a934a58 commit 71289ad

File tree

2 files changed

+17
-11
lines changed

2 files changed

+17
-11
lines changed

src/odb/src/db/dbNet.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2234,20 +2234,24 @@ void dbNet::mergeNet(dbNet* in_net)
22342234
_dbNet* net = (_dbNet*) this;
22352235
_dbBlock* block = (_dbBlock*) net->getOwner();
22362236

2237-
std::vector<dbITerm*> iterms;
2238-
for (dbITerm* iterm : in_net->getITerms()) {
2239-
iterms.push_back(iterm);
2240-
}
2241-
22422237
for (auto callback : block->_callbacks) {
22432238
callback->inDbNetPreMerge(this, in_net);
22442239
}
22452240

2241+
// in_net->getITerms() returns a terminal iterator, and iterm->connect() can
2242+
// invalidate the iterator by disconnecting a dbITerm.
2243+
// Calling iterm->connect() during iteration with the iterator is not safe.
2244+
// Thus create another vector for safe iterms iteration.
2245+
auto iterms_set = in_net->getITerms();
2246+
std::vector<dbITerm*> iterms(iterms_set.begin(), iterms_set.end());
22462247
for (dbITerm* iterm : iterms) {
22472248
iterm->connect(this);
22482249
}
22492250

2250-
for (dbBTerm* bterm : in_net->getBTerms()) {
2251+
// Create vector for safe iteration.
2252+
auto bterms_set = in_net->getBTerms();
2253+
std::vector<dbBTerm*> bterms(bterms_set.begin(), bterms_set.end());
2254+
for (dbBTerm* bterm : bterms) {
22512255
bterm->connect(this);
22522256
}
22532257
}

src/rsz/src/UnbufferMove.cc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ void UnbufferMove::removeBuffer(Instance* buffer)
405405
}
406406
}
407407

408-
// Remove buffer from the database and handle the nets
408+
// Disconnect the buffer and handle the nets
409409
debugPrint(logger_,
410410
RSZ,
411411
"remove_buffer",
@@ -423,10 +423,6 @@ void UnbufferMove::removeBuffer(Instance* buffer)
423423
}
424424
sta_->disconnectPin(in_pin);
425425
sta_->disconnectPin(out_pin);
426-
sta_->deleteInstance(buffer);
427-
if (removed) {
428-
sta_->deleteNet(removed);
429-
}
430426

431427
// Hierarchical case supported:
432428
// moving an output hierarchical net to the input pin driver.
@@ -447,6 +443,12 @@ void UnbufferMove::removeBuffer(Instance* buffer)
447443
db_network_->connectPin(driver_pin, db_network_->dbToSta(op_modnet));
448444
}
449445

446+
// Deletion
447+
sta_->deleteInstance(buffer);
448+
if (removed) {
449+
sta_->deleteNet(removed);
450+
}
451+
450452
estimate_parasitics_->removeNetFromParasiticsInvalid(removed);
451453
estimate_parasitics_->parasiticsInvalid(survivor);
452454
estimate_parasitics_->updateParasitics();

0 commit comments

Comments
 (0)