Bugfix: avoid a segfault

Reason: PCellDeclaration::parameter_declaration is volatile when
the PCell does not want parameter declaration caching. In this
case, begin .. end iterators must not be taken from different
calls to parameter_declaration for example.
This commit is contained in:
Matthias Koefferlein 2017-11-01 22:12:49 +01:00
parent ea5920bda4
commit af1c5c9f66
8 changed files with 44 additions and 27 deletions

View File

@ -1628,20 +1628,22 @@ Layout::reserve_layers (unsigned int n)
static const std::vector<tl::Variant> &gauge_parameters (const std::vector<tl::Variant> &p, const db::PCellDeclaration *pcell_decl, std::vector<tl::Variant> &buffer)
{
if (pcell_decl->parameter_declarations ().size () > p.size ()) {
const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
if (pcp.size () > p.size ()) {
buffer.clear ();
buffer.resize (pcell_decl->parameter_declarations ().size ());
buffer.resize (pcp.size ());
buffer = p;
for (std::vector<PCellParameterDeclaration>::const_iterator i = pcell_decl->parameter_declarations ().begin () + p.size (); i != pcell_decl->parameter_declarations ().end (); ++i) {
for (std::vector<PCellParameterDeclaration>::const_iterator i = pcp.begin () + p.size (); i != pcp.end (); ++i) {
buffer.push_back (i->get_default ());
}
return buffer;
} else if (pcell_decl->parameter_declarations ().size () < p.size ()) {
} else if (pcp.size () < p.size ()) {
buffer.clear ();
buffer.insert (buffer.end (), p.begin (), p.begin () + pcell_decl->parameter_declarations ().size ());
buffer.insert (buffer.end (), p.begin (), p.begin () + pcp.size ());
return buffer;
} else {
@ -1683,8 +1685,9 @@ Layout::get_pcell_variant_dict (pcell_id_type pcell_id, const std::map<std::stri
tl_assert (header != 0);
std::vector<tl::Variant> parameters;
parameters.reserve (header->declaration ()->parameter_declarations ().size ());
for (std::vector<db::PCellParameterDeclaration>::const_iterator pd = header->declaration ()->parameter_declarations ().begin (); pd != header->declaration ()->parameter_declarations ().end(); ++pd) {
const std::vector<db::PCellParameterDeclaration> &pcp = header->declaration ()->parameter_declarations ();
parameters.reserve (pcp.size ());
for (std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end(); ++pd) {
std::map<std::string, tl::Variant>::const_iterator pp = p.find (pd->get_name ());
if (pp == p.end ()) {
parameters.push_back (pd->get_default ());
@ -2024,8 +2027,9 @@ Layout::get_context_info (cell_index_type cell_index, std::vector <std::string>
const db::PCellDeclaration *pcell_decl = ly->pcell_declaration (pcell_variant->pcell_id ());
std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcell_decl->parameter_declarations ().begin ();
for (std::vector<tl::Variant>::const_iterator p = pcell_variant->parameters ().begin (); p != pcell_variant->parameters ().end () && pd != pcell_decl->parameter_declarations ().end (); ++p, ++pd) {
const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcp.begin ();
for (std::vector<tl::Variant>::const_iterator p = pcell_variant->parameters ().begin (); p != pcell_variant->parameters ().end () && pd != pcp.end (); ++p, ++pd) {
context_info.push_back ("P(" + tl::to_word_or_quoted_string (pd->get_name ()) + ")=" + p->to_parsable_string ());
}

View File

@ -53,7 +53,8 @@ PCellDeclaration::map_parameters (const std::map<size_t, tl::Variant> &param_by_
{
db::pcell_parameters_type new_param;
size_t i = 0;
for (std::vector<PCellParameterDeclaration>::const_iterator pd = parameter_declarations ().begin (); pd != parameter_declarations ().end (); ++pd, ++i) {
const std::vector<db::PCellParameterDeclaration> &pcp = parameter_declarations ();
for (std::vector<PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end (); ++pd, ++i) {
std::map<size_t, tl::Variant>::const_iterator p = param_by_name.find (i);
if (p != param_by_name.end ()) {
new_param.push_back (p->second);
@ -69,7 +70,8 @@ pcell_parameters_type
PCellDeclaration::map_parameters (const std::map<std::string, tl::Variant> &param_by_name) const
{
db::pcell_parameters_type new_param;
for (std::vector<PCellParameterDeclaration>::const_iterator pd = parameter_declarations ().begin (); pd != parameter_declarations ().end (); ++pd) {
const std::vector<db::PCellParameterDeclaration> &pcp = parameter_declarations ();
for (std::vector<PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end (); ++pd) {
std::map<std::string, tl::Variant>::const_iterator p = param_by_name.find (pd->get_name ());
if (p != param_by_name.end ()) {
new_param.push_back (p->second);

View File

@ -465,8 +465,9 @@ public:
*/
const std::string &parameter_name (size_t index)
{
if (index < parameter_declarations ().size ()) {
return parameter_declarations () [index].get_name ();
const std::vector<db::PCellParameterDeclaration> &pcp = parameter_declarations ();
if (index < pcp.size ()) {
return pcp [index].get_name ();
} else {
static std::string empty;
return empty;

View File

@ -108,7 +108,8 @@ PCellVariant::parameter_by_name (const std::string &name) const
if (header && header->declaration ()) {
db::pcell_parameters_type::const_iterator pp = parameters ().begin ();
for (std::vector<PCellParameterDeclaration>::const_iterator pd = header->declaration ()->parameter_declarations ().begin (); pd != header->declaration ()->parameter_declarations ().end () && pp != parameters ().end (); ++pd, ++pp) {
const std::vector<db::PCellParameterDeclaration> &pcp = header->declaration ()->parameter_declarations ();
for (std::vector<PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end () && pp != parameters ().end (); ++pd, ++pp) {
if (pd->get_name () == name) {
return *pp;
}
@ -128,7 +129,8 @@ PCellVariant::parameters_by_name () const
if (header && header->declaration ()) {
db::pcell_parameters_type::const_iterator pp = parameters ().begin ();
for (std::vector<PCellParameterDeclaration>::const_iterator pd = header->declaration ()->parameter_declarations ().begin (); pd != header->declaration ()->parameter_declarations ().end () && pp != parameters ().end (); ++pd, ++pp) {
const std::vector<db::PCellParameterDeclaration> &pcp = header->declaration ()->parameter_declarations ();
for (std::vector<PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end () && pp != parameters ().end (); ++pd, ++pp) {
param_by_name.insert (std::make_pair (pd->get_name (), *pp));
}
@ -167,7 +169,8 @@ PCellVariant::update (ImportLayerMapping *layer_mapping)
// produce the shape parameters on the guiding shape layer so they can be edited
size_t i = 0;
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = header->declaration ()->parameter_declarations ().begin (); p != header->declaration ()->parameter_declarations ().end (); ++p, ++i) {
const std::vector<db::PCellParameterDeclaration> &pcp = header->declaration ()->parameter_declarations ();
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++i) {
if (i < m_parameters.size () && p->get_type () == db::PCellParameterDeclaration::t_shape && ! p->is_hidden ()) {

View File

@ -635,8 +635,9 @@ EditorOptionsInst::apply (lay::Plugin *root)
const db::PCellDeclaration *pc_decl = layout->pcell_declaration (pc.second);
if (pc_decl) {
std::vector<tl::Variant> pv = mp_pcell_parameters->get_parameters ();
for (size_t i = 0; i < std::min (pv.size (), pc_decl->parameter_declarations ().size ()); ++i) {
param += tl::to_word_or_quoted_string (pc_decl->parameter_declarations () [i].get_name ()) + ":";
const std::vector<db::PCellParameterDeclaration> &pcp = pc_decl->parameter_declarations ();
for (size_t i = 0; i < std::min (pv.size (), pcp.size ()); ++i) {
param += tl::to_word_or_quoted_string (pcp [i].get_name ()) + ":";
param += pv [i].to_parsable_string ();
param += ";";
}
@ -741,7 +742,8 @@ EditorOptionsInst::setup (lay::Plugin *root)
}
} catch (...) { }
for (std::vector<db::PCellParameterDeclaration>::const_iterator pd = pc_decl->parameter_declarations ().begin (); pd != pc_decl->parameter_declarations ().end (); ++pd) {
const std::vector<db::PCellParameterDeclaration> &pcp = pc_decl->parameter_declarations ();
for (std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end (); ++pd) {
std::map<std::string, tl::Variant>::const_iterator p = parameters.find (pd->get_name ());
if (p != parameters.end ()) {
pv.push_back (p->second);

View File

@ -147,7 +147,8 @@ PCellParametersPage::PCellParametersPage (QWidget *parent, const db::Layout *lay
std::string group_title;
int r = 0;
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcell_decl->parameter_declarations ().begin (); p != pcell_decl->parameter_declarations ().end (); ++p, ++r) {
const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
if (p->is_hidden () || p->get_type () == db::PCellParameterDeclaration::t_shape) {
m_widgets.push_back (0);
@ -321,7 +322,8 @@ PCellParametersPage::get_parameters ()
std::vector<tl::Variant> parameters;
int r = 0;
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = mp_pcell_decl->parameter_declarations ().begin (); p != mp_pcell_decl->parameter_declarations ().end (); ++p, ++r) {
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
if (p->is_hidden () || p->get_type () == db::PCellParameterDeclaration::t_shape) {
@ -427,7 +429,8 @@ PCellParametersPage::set_parameters (const std::vector<tl::Variant> &parameters
{
// write the changed value back
size_t r = 0;
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = mp_pcell_decl->parameter_declarations ().begin (); p != mp_pcell_decl->parameter_declarations ().end (); ++p, ++r) {
const std::vector<db::PCellParameterDeclaration> &pcp = mp_pcell_decl->parameter_declarations ();
for (std::vector<db::PCellParameterDeclaration>::const_iterator p = pcp.begin (); p != pcp.end (); ++p, ++r) {
if (r < parameters.size () && m_widgets [r]) {
set_value (*p, mp_layout, m_widgets [r], parameters [r]);
}

View File

@ -1311,7 +1311,8 @@ InstService::make_cell (const lay::CellView &cv)
ex.test (";");
}
for (std::vector<db::PCellParameterDeclaration>::const_iterator pd = pc_decl->parameter_declarations ().begin (); pd != pc_decl->parameter_declarations ().end (); ++pd) {
const std::vector<db::PCellParameterDeclaration> &pcp = pc_decl->parameter_declarations ();
for (std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcp.begin (); pd != pcp.end (); ++pd) {
std::map<std::string, tl::Variant>::const_iterator p = parameters.find (pd->get_name ());
if (p != parameters.end ()) {
pv.push_back (p->second);

View File

@ -125,12 +125,13 @@ get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index
// convert the guiding shapes to parameters
parameters_for_pcell = def_layout->get_pcell_parameters (lc.second);
const db::PCellDeclaration *pcell_decl = def_layout->pcell_declaration (lpc.second);
const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
db::pcell_parameters_type org_parameters = parameters_for_pcell;
std::map <std::string, size_t> pname_map;
for (size_t i = 0; i < pcell_decl->parameter_declarations ().size () && i < parameters_for_pcell.size (); ++i) {
pname_map.insert (std::make_pair (pcell_decl->parameter_declarations () [i].get_name (), i));
for (size_t i = 0; i < pcp.size () && i < parameters_for_pcell.size (); ++i) {
pname_map.insert (std::make_pair (pcp [i].get_name (), i));
}
db::property_names_id_type pn = layout->properties_repository ().prop_name_id ("name");
@ -180,9 +181,9 @@ get_parameters_from_pcell_and_guiding_shapes (db::Layout *layout, db::cell_index
// create a variant in the calling code we have to revert the shapes back to their initial state which
// is consistent with the parameters.
guiding_shapes.clear ();
for (size_t i = 0; i < pcell_decl->parameter_declarations ().size () && i < org_parameters.size (); ++i) {
for (size_t i = 0; i < pcp.size () && i < org_parameters.size (); ++i) {
const db::PCellParameterDeclaration &pd = pcell_decl->parameter_declarations () [i];
const db::PCellParameterDeclaration &pd = pcp [i];
if (pd.get_type () == db::PCellParameterDeclaration::t_shape && ! pd.is_hidden ()) {