Fix for br991 - compiler crashes due to null statements.
The reported problem was caused by a null statement in a case statement, which caused the check for an infinite loop to fail. Further testing exposed more problems with null statements in loop statements - these caused crashes earlier in elaboration.
This commit is contained in:
parent
e2a1f21896
commit
e682166253
51
elaborate.cc
51
elaborate.cc
|
|
@ -4039,9 +4039,18 @@ NetProc* PDisable::elaborate(Design*des, NetScope*scope) const
|
||||||
*/
|
*/
|
||||||
NetProc* PDoWhile::elaborate(Design*des, NetScope*scope) const
|
NetProc* PDoWhile::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
NetExpr*tmp = elab_and_eval(des, scope, cond_, -1);
|
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
|
||||||
tmp->set_line(*this);
|
NetProc*sub;
|
||||||
NetDoWhile*loop = new NetDoWhile(tmp, statement_->elaborate(des, scope));
|
if (statement_)
|
||||||
|
sub = statement_->elaborate(des, scope);
|
||||||
|
else
|
||||||
|
sub = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
if (ce == 0 || sub == 0) {
|
||||||
|
delete ce;
|
||||||
|
delete sub;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
NetDoWhile*loop = new NetDoWhile(ce, sub);
|
||||||
loop->set_line(*this);
|
loop->set_line(*this);
|
||||||
return loop;
|
return loop;
|
||||||
}
|
}
|
||||||
|
|
@ -4572,7 +4581,11 @@ NetProc* PEventStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
*/
|
*/
|
||||||
NetProc* PForever::elaborate(Design*des, NetScope*scope) const
|
NetProc* PForever::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
NetProc*stat = statement_->elaborate(des, scope);
|
NetProc*stat;
|
||||||
|
if (statement_)
|
||||||
|
stat = statement_->elaborate(des, scope);
|
||||||
|
else
|
||||||
|
stat = new NetBlock(NetBlock::SEQU, 0);
|
||||||
if (stat == 0) return 0;
|
if (stat == 0) return 0;
|
||||||
|
|
||||||
NetForever*proc = new NetForever(stat);
|
NetForever*proc = new NetForever(stat);
|
||||||
|
|
@ -4778,7 +4791,11 @@ NetProc* PForeach::elaborate(Design*des, NetScope*scope) const
|
||||||
|
|
||||||
/* Elaborate the statement that is contained in the foreach
|
/* Elaborate the statement that is contained in the foreach
|
||||||
loop. */
|
loop. */
|
||||||
NetProc*sub = statement_->elaborate(des, scope);
|
NetProc*sub;
|
||||||
|
if (statement_)
|
||||||
|
sub = statement_->elaborate(des, scope);
|
||||||
|
else
|
||||||
|
sub = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
|
||||||
/* Make a step statement: idx += 1 */
|
/* Make a step statement: idx += 1 */
|
||||||
NetAssign_*idx_lv = new NetAssign_(idx_sig);
|
NetAssign_*idx_lv = new NetAssign_(idx_sig);
|
||||||
|
|
@ -4809,7 +4826,11 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope,
|
||||||
ivl_assert(*this, index_vars_.size() > 0);
|
ivl_assert(*this, index_vars_.size() > 0);
|
||||||
ivl_assert(*this, dims.size() == index_vars_.size());
|
ivl_assert(*this, dims.size() == index_vars_.size());
|
||||||
|
|
||||||
NetProc*sub = statement_->elaborate(des, scope);
|
NetProc*sub;
|
||||||
|
if (statement_)
|
||||||
|
sub = statement_->elaborate(des, scope);
|
||||||
|
else
|
||||||
|
sub = new NetBlock(NetBlock::SEQU, 0);
|
||||||
NetForLoop*stmt = 0;
|
NetForLoop*stmt = 0;
|
||||||
|
|
||||||
for (int idx_idx = index_vars_.size()-1 ; idx_idx >= 0 ; idx_idx -= 1) {
|
for (int idx_idx = index_vars_.size()-1 ; idx_idx >= 0 ; idx_idx -= 1) {
|
||||||
|
|
@ -4903,7 +4924,11 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
loop. If there is an error, this will return 0 and I should
|
loop. If there is an error, this will return 0 and I should
|
||||||
skip the append. No need to worry, the error has been
|
skip the append. No need to worry, the error has been
|
||||||
reported so it's OK that the netlist is bogus. */
|
reported so it's OK that the netlist is bogus. */
|
||||||
NetProc*sub = statement_->elaborate(des, scope);
|
NetProc*sub;
|
||||||
|
if (statement_)
|
||||||
|
sub = statement_->elaborate(des, scope);
|
||||||
|
else
|
||||||
|
sub = new NetBlock(NetBlock::SEQU, 0);
|
||||||
|
|
||||||
/* Now elaborate the for_step statement. I really should do
|
/* Now elaborate the for_step statement. I really should do
|
||||||
some error checking here to make sure the step statement
|
some error checking here to make sure the step statement
|
||||||
|
|
@ -5025,7 +5050,11 @@ NetProc* PRepeat::elaborate(Design*des, NetScope*scope) const
|
||||||
if (expr->expr_type() == IVL_VT_REAL)
|
if (expr->expr_type() == IVL_VT_REAL)
|
||||||
expr = cast_to_int4(expr, 64);
|
expr = cast_to_int4(expr, 64);
|
||||||
|
|
||||||
NetProc*stat = statement_->elaborate(des, scope);
|
NetProc*stat;
|
||||||
|
if (statement_)
|
||||||
|
stat = statement_->elaborate(des, scope);
|
||||||
|
else
|
||||||
|
stat = new NetBlock(NetBlock::SEQU, 0);
|
||||||
if (stat == 0) return 0;
|
if (stat == 0) return 0;
|
||||||
|
|
||||||
// If the expression is a constant, handle certain special
|
// If the expression is a constant, handle certain special
|
||||||
|
|
@ -5205,7 +5234,11 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const
|
||||||
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
|
NetProc* PWhile::elaborate(Design*des, NetScope*scope) const
|
||||||
{
|
{
|
||||||
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
|
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
|
||||||
NetProc*sub = statement_->elaborate(des, scope);
|
NetProc*sub;
|
||||||
|
if (statement_)
|
||||||
|
sub = statement_->elaborate(des, scope);
|
||||||
|
else
|
||||||
|
sub = new NetBlock(NetBlock::SEQU, 0);
|
||||||
if (ce == 0 || sub == 0) {
|
if (ce == 0 || sub == 0) {
|
||||||
delete ce;
|
delete ce;
|
||||||
delete sub;
|
delete sub;
|
||||||
|
|
|
||||||
10
netlist.cc
10
netlist.cc
|
|
@ -2743,10 +2743,11 @@ DelayType NetCase::delay_type() const
|
||||||
|
|
||||||
for (unsigned idx = 0; idx < nstmts; idx += 1) {
|
for (unsigned idx = 0; idx < nstmts; idx += 1) {
|
||||||
if (!expr(idx)) def_stmt = true;
|
if (!expr(idx)) def_stmt = true;
|
||||||
|
DelayType dt = stat(idx) ? stat(idx)->delay_type() : NO_DELAY;
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
result = stat(idx)->delay_type();
|
result = dt;
|
||||||
} else {
|
} else {
|
||||||
result = combine_delays(result, stat(idx)->delay_type());
|
result = combine_delays(result, dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2769,6 +2770,7 @@ DelayType NetCondit::delay_type() const
|
||||||
*/
|
*/
|
||||||
DelayType NetDoWhile::delay_type() const
|
DelayType NetDoWhile::delay_type() const
|
||||||
{
|
{
|
||||||
|
ivl_assert(*this, proc_);
|
||||||
return proc_->delay_type();
|
return proc_->delay_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2779,11 +2781,13 @@ DelayType NetEvWait::delay_type() const
|
||||||
|
|
||||||
DelayType NetForever::delay_type() const
|
DelayType NetForever::delay_type() const
|
||||||
{
|
{
|
||||||
|
ivl_assert(*this, statement_);
|
||||||
return statement_->delay_type();
|
return statement_->delay_type();
|
||||||
}
|
}
|
||||||
|
|
||||||
DelayType NetForLoop::delay_type() const
|
DelayType NetForLoop::delay_type() const
|
||||||
{
|
{
|
||||||
|
ivl_assert(*this, statement_);
|
||||||
return get_loop_delay_type(condition_, statement_);
|
return get_loop_delay_type(condition_, statement_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2806,6 +2810,7 @@ DelayType NetPDelay::delay_type() const
|
||||||
|
|
||||||
DelayType NetRepeat::delay_type() const
|
DelayType NetRepeat::delay_type() const
|
||||||
{
|
{
|
||||||
|
ivl_assert(*this, statement_);
|
||||||
return get_loop_delay_type(expr_, statement_);
|
return get_loop_delay_type(expr_, statement_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2821,5 +2826,6 @@ DelayType NetUTask::delay_type() const
|
||||||
|
|
||||||
DelayType NetWhile::delay_type() const
|
DelayType NetWhile::delay_type() const
|
||||||
{
|
{
|
||||||
|
ivl_assert(*this, proc_);
|
||||||
return get_loop_delay_type(cond_, proc_);
|
return get_loop_delay_type(cond_, proc_);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue