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:
Martin Whitaker 2015-08-17 21:47:15 +01:00
parent e2a1f21896
commit e682166253
2 changed files with 50 additions and 11 deletions

View File

@ -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;

View File

@ -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_);
} }