Elaborate alternate constant ternary expressions to check for errors

This commit is contained in:
Cary R 2021-01-29 17:48:17 -08:00
parent 348bc13a21
commit 9e3d6cc996
2 changed files with 22 additions and 5 deletions

View File

@ -6758,11 +6758,8 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
/* Make sure the condition expression reduces to a single bit. */
con = condition_reduce(con);
// Verilog doesn't say that we must do short circuit
// evaluation of ternary expressions, but it doesn't disallow
// it. The disadvantage of doing this is that semantic errors
// in the unused clause will be missed, but people don't seem
// to mind, and do appreciate the optimization available here.
// Verilog doesn't say that we must do short circuit evaluation
// of ternary expressions, but it doesn't disallow it.
if (NetEConst*tmp = dynamic_cast<NetEConst*> (con)) {
verinum cval = tmp->value();
ivl_assert(*this, cval.len()==1);
@ -6774,6 +6771,13 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
"elaborate TRUE clause of ternary."
<< endl;
// Evaluate the alternate expression to find any errors.
NetExpr*dmy = elab_and_eval_alternative_(des, scope, fal_,
expr_wid, flags,
true);
delete dmy;
delete con;
return elab_and_eval_alternative_(des, scope, tru_,
expr_wid, flags, true);
}
@ -6786,6 +6790,13 @@ NetExpr*PETernary::elaborate_expr(Design*des, NetScope*scope,
"elaborate FALSE clause of ternary."
<< endl;
// Evaluate the alternate expression to find any errors.
NetExpr*dmy = elab_and_eval_alternative_(des, scope, tru_,
expr_wid, flags,
true);
delete dmy;
delete con;
return elab_and_eval_alternative_(des, scope, fal_,
expr_wid, flags, true);
}

View File

@ -1243,6 +1243,9 @@ NetExpr* NetETernary::eval_tree()
<< *false_val_ << endl;
}
// Elaborate the alternate expression to check for errors.
eval_expr(true_val_);
if (expr_type() == IVL_VT_REAL &&
false_val_->expr_type() != IVL_VT_REAL) {
verireal f;
@ -1265,6 +1268,9 @@ NetExpr* NetETernary::eval_tree()
<< *true_val_ << endl;
}
// Elaborate the alternate expression to check for errors.
eval_expr(false_val_);
if (expr_type() == IVL_VT_REAL &&
true_val_->expr_type() != IVL_VT_REAL) {
verireal t;