From c4ff8300d3c4a59b8c6df3000e6f657222d2637d Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Thu, 26 Jul 2012 18:08:18 +0100 Subject: [PATCH] Handle error case of zero width in indexed part select. The compiler doesn't currently check that the width of an indexed part select is non-zero. If code contains this erroneous case, the compiler can crash (with an assertion failure). This patch causes the compiler to output a suitable error message and recover. It also fixes a potential crash if an illegal expresson is encountered. --- elab_expr.cc | 15 +++++++++------ expr_synth.cc | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index 7d10bb0d8..e4c835ac3 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2095,15 +2095,18 @@ bool PEIdent::calculate_up_do_width_(Design*des, NetScope*scope, NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1, true); NetEConst*wid_c = dynamic_cast(wid_ex); - if (wid_c == 0) { - cerr << get_fileline() << ": error: Indexed part width must be " - << "constant. Expression in question is..." << endl; - cerr << get_fileline() << ": : " << *wid_ex << endl; + wid = wid_c? wid_c->value().as_ulong() : 0; + if (wid == 0) { + cerr << index_tail.lsb->get_fileline() << ": error: " + "Indexed part widths must be constant and greater than zero." + << endl; + cerr << index_tail.lsb->get_fileline() << ": : " + "This part width expression violates the rule: " + << *index_tail.lsb << endl; des->errors += 1; flag = false; + wid = 1; } - - wid = wid_c? wid_c->value().as_ulong() : 1; delete wid_ex; return flag; diff --git a/expr_synth.cc b/expr_synth.cc index e30940025..d1877ecc7 100644 --- a/expr_synth.cc +++ b/expr_synth.cc @@ -1064,6 +1064,7 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root) NetPartSelect::VP); des->add_node(sel); + ivl_assert(*this, select_width > 0); NetNet*tmp = new NetNet(scope, scope->local_symbol(), NetNet::WIRE, select_width); tmp->set_line(*this);