mirror of https://github.com/KLayout/klayout.git
Using a weak Layout pointer to avoid segfaults in RecursiveShapeIterator
This commit is contained in:
parent
e2c6e7aedc
commit
c0b38f3706
|
|
@ -93,7 +93,6 @@ RecursiveShapeIterator::RecursiveShapeIterator ()
|
|||
// anything. Not necessary reasonable.
|
||||
m_layer = 0;
|
||||
m_has_layers = false;
|
||||
mp_layout = 0;
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = 0;
|
||||
mp_cell = 0;
|
||||
|
|
@ -113,7 +112,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes)
|
|||
{
|
||||
m_layer = 0;
|
||||
m_has_layers = false;
|
||||
mp_layout = 0;
|
||||
mp_shapes = &shapes;
|
||||
mp_top_cell = 0;
|
||||
m_overlapping = false;
|
||||
|
|
@ -125,7 +123,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const
|
|||
{
|
||||
m_layer = 0;
|
||||
m_has_layers = false;
|
||||
mp_layout = 0;
|
||||
mp_shapes = &shapes;
|
||||
mp_top_cell = 0;
|
||||
m_overlapping = overlapping;
|
||||
|
|
@ -137,7 +134,6 @@ RecursiveShapeIterator::RecursiveShapeIterator (const shapes_type &shapes, const
|
|||
{
|
||||
m_layer = 0;
|
||||
m_has_layers = false;
|
||||
mp_layout = 0;
|
||||
mp_shapes = &shapes;
|
||||
mp_top_cell = 0;
|
||||
m_overlapping = overlapping;
|
||||
|
|
@ -150,7 +146,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
{
|
||||
m_layer = layer;
|
||||
m_has_layers = false;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = overlapping;
|
||||
|
|
@ -163,7 +159,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
{
|
||||
m_layer = layer;
|
||||
m_has_layers = false;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = overlapping;
|
||||
|
|
@ -176,7 +172,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
{
|
||||
m_layer = layer;
|
||||
m_has_layers = false;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = false;
|
||||
|
|
@ -190,7 +186,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
m_layer = 0;
|
||||
m_layers = layers;
|
||||
m_has_layers = true;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = overlapping;
|
||||
|
|
@ -204,7 +200,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
m_layer = 0;
|
||||
m_layers = layers;
|
||||
m_has_layers = true;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = overlapping;
|
||||
|
|
@ -218,7 +214,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
m_layer = 0;
|
||||
m_layers = layers;
|
||||
m_has_layers = true;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = false;
|
||||
|
|
@ -232,7 +228,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
m_layer = 0;
|
||||
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
||||
m_has_layers = true;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = overlapping;
|
||||
|
|
@ -246,7 +242,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
m_layer = 0;
|
||||
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
||||
m_has_layers = true;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = overlapping;
|
||||
|
|
@ -260,7 +256,7 @@ RecursiveShapeIterator::RecursiveShapeIterator (const layout_type &layout, const
|
|||
m_layer = 0;
|
||||
m_layers.insert (m_layers.end (), layers.begin (), layers.end ());
|
||||
m_has_layers = true;
|
||||
mp_layout = &layout;
|
||||
mp_layout.reset (const_cast<db::Layout *> (&layout));
|
||||
mp_shapes = 0;
|
||||
mp_top_cell = &cell;
|
||||
m_overlapping = false;
|
||||
|
|
@ -691,6 +687,8 @@ RecursiveShapeIterator::next_shape (RecursiveShapeReceiver *receiver) const
|
|||
|
||||
if (! m_inst.at_end () && int (m_inst_iterators.size ()) < m_max_depth) {
|
||||
|
||||
tl_assert (mp_layout);
|
||||
|
||||
// determine whether the cell is empty with respect to the layers specified
|
||||
bool is_empty = false;
|
||||
if (! m_has_layers) {
|
||||
|
|
@ -754,6 +752,8 @@ RecursiveShapeIterator::next_shape (RecursiveShapeReceiver *receiver) const
|
|||
void
|
||||
RecursiveShapeIterator::down (RecursiveShapeReceiver *receiver) const
|
||||
{
|
||||
tl_assert (mp_layout);
|
||||
|
||||
m_trans_stack.push_back (m_trans);
|
||||
m_cells.push_back (mp_cell);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "dbLayout.h"
|
||||
#include "dbInstElement.h"
|
||||
#include "tlAssert.h"
|
||||
#include "tlObject.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
|
@ -306,7 +307,7 @@ public:
|
|||
*/
|
||||
const layout_type *layout () const
|
||||
{
|
||||
return mp_layout;
|
||||
return mp_layout.get ();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -765,7 +766,7 @@ private:
|
|||
std::set<db::cell_index_type> m_start, m_stop;
|
||||
cplx_trans_type m_global_trans;
|
||||
|
||||
const layout_type *mp_layout;
|
||||
tl::weak_ptr<layout_type> mp_layout;
|
||||
const cell_type *mp_top_cell;
|
||||
const shapes_type *mp_shapes;
|
||||
|
||||
|
|
|
|||
|
|
@ -1515,3 +1515,42 @@ TEST(10)
|
|||
"end\n"
|
||||
);
|
||||
}
|
||||
|
||||
TEST(11_LayoutIsWeakPointer)
|
||||
{
|
||||
std::unique_ptr<db::Layout> g (new db::Layout ());
|
||||
g->insert_layer (0);
|
||||
g->insert_layer (1);
|
||||
db::Cell &c0 (g->cell (g->add_cell ()));
|
||||
db::Cell &c1 (g->cell (g->add_cell ()));
|
||||
db::Cell &c2 (g->cell (g->add_cell ()));
|
||||
db::Cell &c3 (g->cell (g->add_cell ()));
|
||||
|
||||
db::Box b (0, 100, 1000, 1200);
|
||||
c1.shapes (0).insert (b);
|
||||
c2.shapes (0).insert (b);
|
||||
c3.shapes (0).insert (b);
|
||||
|
||||
db::Box bb (1, 101, 1001, 1201);
|
||||
c2.shapes (1).insert (bb);
|
||||
|
||||
db::Trans tt;
|
||||
c0.insert (db::CellInstArray (db::CellInst (c1.cell_index ()), tt));
|
||||
c0.insert (db::CellInstArray (db::CellInst (c2.cell_index ()), db::Trans (db::Vector (100, -100))));
|
||||
c0.insert (db::CellInstArray (db::CellInst (c3.cell_index ()), db::Trans (1)));
|
||||
c2.insert (db::CellInstArray (db::CellInst (c3.cell_index ()), db::Trans (db::Vector (1100, 0))));
|
||||
|
||||
std::string x;
|
||||
|
||||
db::RecursiveShapeIterator i1 (*g, c0, 0, db::Box (0, 0, 100, 100));
|
||||
x = collect(i1, *g);
|
||||
EXPECT_EQ (x, "[$2](0,100;1000,1200)/[$3](100,0;1100,1100)");
|
||||
|
||||
g.reset (new db::Layout ());
|
||||
|
||||
// now the layout is gone and the iterator stays silent (weak pointer to layout)
|
||||
// NOTE: this only works on reset or re-initialization. Not during iteration.
|
||||
i1.reset ();
|
||||
x = collect(i1, *g);
|
||||
EXPECT_EQ (x, "");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue