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.
This commit is contained in:
parent
a5a512758e
commit
c4ff8300d3
15
elab_expr.cc
15
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);
|
NetExpr*wid_ex = elab_and_eval(des, scope, index_tail.lsb, -1, true);
|
||||||
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
|
NetEConst*wid_c = dynamic_cast<NetEConst*>(wid_ex);
|
||||||
|
|
||||||
if (wid_c == 0) {
|
wid = wid_c? wid_c->value().as_ulong() : 0;
|
||||||
cerr << get_fileline() << ": error: Indexed part width must be "
|
if (wid == 0) {
|
||||||
<< "constant. Expression in question is..." << endl;
|
cerr << index_tail.lsb->get_fileline() << ": error: "
|
||||||
cerr << get_fileline() << ": : " << *wid_ex << endl;
|
"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;
|
des->errors += 1;
|
||||||
flag = false;
|
flag = false;
|
||||||
|
wid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wid = wid_c? wid_c->value().as_ulong() : 1;
|
|
||||||
delete wid_ex;
|
delete wid_ex;
|
||||||
|
|
||||||
return flag;
|
return flag;
|
||||||
|
|
|
||||||
|
|
@ -1064,6 +1064,7 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||||
NetPartSelect::VP);
|
NetPartSelect::VP);
|
||||||
des->add_node(sel);
|
des->add_node(sel);
|
||||||
|
|
||||||
|
ivl_assert(*this, select_width > 0);
|
||||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||||
NetNet::WIRE, select_width);
|
NetNet::WIRE, select_width);
|
||||||
tmp->set_line(*this);
|
tmp->set_line(*this);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue