diff --git a/src/db/db/dbLibraryProxy.cc b/src/db/db/dbLibraryProxy.cc index 92e0e27b4..4008a1253 100644 --- a/src/db/db/dbLibraryProxy.cc +++ b/src/db/db/dbLibraryProxy.cc @@ -42,14 +42,18 @@ LibraryProxy::LibraryProxy (db::cell_index_type ci, db::Layout &layout, lib_id_t LibraryProxy::~LibraryProxy () { - if (layout ()) { - layout ()->unregister_lib_proxy (this); - } - if (db::LibraryManager::initialized ()) { - db::Library *lib = db::LibraryManager::instance ().lib (m_lib_id); - if (lib) { - lib->unregister_proxy (this, layout ()); + try { + if (layout ()) { + layout ()->unregister_lib_proxy (this); } + if (db::LibraryManager::initialized ()) { + db::Library *lib = db::LibraryManager::instance ().lib (m_lib_id); + if (lib) { + lib->unregister_proxy (this, layout ()); + } + } + } catch (...) { + // ignore exceptions (may happen due to broken PCell instantiations) } } diff --git a/src/db/db/gsiDeclDbCell.cc b/src/db/db/gsiDeclDbCell.cc index 8d0bd4bcd..fce707adf 100644 --- a/src/db/db/gsiDeclDbCell.cc +++ b/src/db/db/gsiDeclDbCell.cc @@ -708,8 +708,19 @@ static gsi::layout_locking_iterator1 begin_overlappi return gsi::layout_locking_iterator1 (s->layout (), s->begin_overlapping (layer_index, db::CplxTrans (layout->dbu ()).inverted () * box, db::ShapeIterator::All)); } +static db::Instance insert_inst (db::Cell *c, const db::Cell::cell_inst_array_type &inst) +{ + if (c->layout () && ! c->layout ()->is_valid_cell_index (inst.object ().cell_index ())) { + throw tl::Exception (tl::to_string (tr ("Cell index is not valid"))); + } + return c->insert (inst); +} + static db::Instance insert_inst_with_props (db::Cell *c, const db::Cell::cell_inst_array_type &inst, db::properties_id_type id) { + if (c->layout () && ! c->layout ()->is_valid_cell_index (inst.object ().cell_index ())) { + throw tl::Exception (tl::to_string (tr ("Cell index is not valid"))); + } if (id) { return c->insert (db::CellInstArrayWithProperties (inst, id)); } else { @@ -2393,7 +2404,7 @@ Class decl_Cell ("db", "Cell", "\n" "It has been added in version 0.16." ) + - gsi::method ("insert", (db::Instance (db::Cell::*)(const db::Cell::cell_inst_array_type &)) &db::Cell::insert, gsi::arg ("cell_inst_array"), + gsi::method_ext ("insert", &insert_inst, gsi::arg ("cell_inst_array"), "@brief Inserts a cell instance (array)\n" "@return An Instance object representing the new instance\n" "With version 0.16, this method returns an Instance object that represents the new instance.\n" diff --git a/testdata/ruby/dbLayout.rb b/testdata/ruby/dbLayout.rb index 9479f4f84..4b9f82480 100644 --- a/testdata/ruby/dbLayout.rb +++ b/testdata/ruby/dbLayout.rb @@ -2024,6 +2024,55 @@ class DBLayout_TestClass < TestBase end + def test_22 + + # invalid cell indexes + + l = RBA::Layout.new + l.insert_layer_at(0, RBA::LayerInfo.new(1, 0)) + c0 = l.cell(l.add_cell("c0")) + c1 = l.cell(l.add_cell("c1")) + assert_equal(c0.cell_index, 0) + assert_equal(c1.cell_index, 1) + + tt = RBA::Trans.new + + error = 0 + begin + c0.insert(RBA::CellInstArray.new(2, tt)) + rescue + error = 1 + end + assert_equal(error, 1) + + error = 0 + begin + c0.insert(RBA::CellInstArray.new(2, tt), 17) + rescue + error = 1 + end + assert_equal(error, 1) + + dtt = RBA::DTrans.new + + error = 0 + begin + c0.insert(RBA::DCellInstArray.new(2, dtt)) + rescue + error = 1 + end + assert_equal(error, 1) + + error = 0 + begin + c0.insert(RBA::DCellInstArray.new(2, dtt), 42) + rescue + error = 1 + end + assert_equal(error, 1) + + end + # Iterating while flatten def test_issue200