From 9e3d6cc996530bb137a885784af557afcdda951d Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 29 Jan 2021 17:48:17 -0800 Subject: [PATCH] Elaborate alternate constant ternary expressions to check for errors --- elab_expr.cc | 21 ++++++++++++++++----- eval_tree.cc | 6 ++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index e7e839188..bb336d04a 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -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 (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); } diff --git a/eval_tree.cc b/eval_tree.cc index ca087c50c..a791760df 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -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;