From 8b34aa78a98940e4b86ab252e00cfa8f16a5d513 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 26 Nov 2024 13:43:27 -0500 Subject: [PATCH] Corrected a long-standing crash condition that happens when a generated cell is modified multiple times. If the original cell is orphaned (no longer used anywhere in the design), it is deleted. However, an instance of the cell may exist in the secondary select buffer if the cell was previously moved or copied, and an attempt to do another move or copy will clear the secondary select buffer, encounter the deleted cell, and crash the program. --- VERSION | 2 +- database/DBcellname.c | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/VERSION b/VERSION index cc6f30d2..84fa2b89 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.501 +8.3.502 diff --git a/database/DBcellname.c b/database/DBcellname.c index faf10fc6..e493a3cf 100644 --- a/database/DBcellname.c +++ b/database/DBcellname.c @@ -224,7 +224,7 @@ DBCellDelete(cellname, force) { HashEntry *entry; CellDef *celldef; - CellUse *celluse; + CellUse *celluse, *lastuse; bool result; entry = HashLookOnly(&dbCellDefTable, cellname); @@ -259,6 +259,29 @@ DBCellDelete(cellname, force) return FALSE; } + /* 2nd pass: If there are instances of the cell in */ + /* internal cells like SelectDef, etc., then remove the use */ + /* from the definition. */ + + lastuse = NULL; + celluse = celldef->cd_parents; + while (celluse != (CellUse *) NULL) + { + if (celluse->cu_parent != (CellDef *)NULL) + { + if ((celluse->cu_parent->cd_flags & CDINTERNAL) == CDINTERNAL) + { + DBDeleteCell(celluse); + celluse = lastuse; + } + } + lastuse = celluse; + if (lastuse == NULL) + celluse = celldef->cd_parents; + else + celluse = celluse->cu_nextuse; + } + /* Cleared to delete. . . now prompt user if the cell has changes. */ /* Last chance to save! */