From 51025149a9bd145bbae32a6f22306a8dbf6beb59 Mon Sep 17 00:00:00 2001 From: Cary R Date: Sun, 27 Dec 2020 19:03:44 -0800 Subject: [PATCH] Report operators that cannot be used with null/class vars --- elab_expr.cc | 53 ++++++++++++++++++++++++++++++++++++++++++++- eval_tree.cc | 7 ------ netmisc.cc | 7 ++++++ tgt-vvp/eval_vec4.c | 15 +++++++++++-- 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index e5266804f..9466910a1 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -277,6 +277,13 @@ unsigned PEBinary::test_width(Design*des, NetScope*scope, width_mode_t&mode) ivl_variable_type_t l_type = left_->expr_type(); ivl_variable_type_t r_type = right_->expr_type(); + if (l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) { + cerr << get_fileline() << ": error: " + << "Class/null is not allowed with the '" + << human_readable_op(op_) << "' operator." << endl; + des->errors += 1; + } + if (l_type == IVL_VT_REAL || r_type == IVL_VT_REAL) expr_type_ = IVL_VT_REAL; else if (l_type == IVL_VT_LOGIC || r_type == IVL_VT_LOGIC) @@ -622,6 +629,34 @@ unsigned PEBComp::test_width(Design*des, NetScope*scope, width_mode_t&) << r_width_ << " bits." << endl; } + switch (op_) { + case 'e': /* == */ + case 'n': /* != */ + case 'E': /* === */ + case 'N': /* !== */ + // FIXME: A class variable/array inside a class is not + // reported correctly so this cannot be used. +#if 0 + if ((l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) && + l_type != r_type) { + cerr << get_fileline() << ": error: " + << "Both arguments ("<< l_type << ", " << r_type + << ") must be class/null for '" + << human_readable_op(op_) << "' operator." << endl; + des->errors += 1; + } +#endif + break; + default: + if (l_type == IVL_VT_CLASS || r_type == IVL_VT_CLASS) { + cerr << get_fileline() << ": error: " + << "Class/null is not allowed with the '" + << human_readable_op(op_) << "' operator." << endl; + des->errors += 1; + } + } + + return expr_width_; } @@ -755,6 +790,13 @@ unsigned PEBLeftWidth::test_width(Design*des, NetScope*scope, width_mode_t&mode) expr_type_ = left_->expr_type(); signed_flag_ = left_->has_sign(); + if (expr_type_ == IVL_VT_CLASS || right_->expr_type() == IVL_VT_CLASS) { + cerr << get_fileline() << ": error: " + << "Class/null is not allowed with the '" + << human_readable_op(op_) << "' operator." << endl; + des->errors += 1; + } + if (mode==SIZED) mode = l_mode; @@ -6282,6 +6324,16 @@ NetExpr*PETypename::elaborate_expr(Design*des, NetScope*, unsigned PEUnary::test_width(Design*des, NetScope*scope, width_mode_t&mode) { + // Evaluate the expression width to get the correct type information + expr_width_ = expr_->test_width(des, scope, mode); + + if (expr_->expr_type() == IVL_VT_CLASS) { + cerr << get_fileline() << ": error: " + << "Class/null is not allowed with the '" + << human_readable_op(op_) << "' operator." << endl; + des->errors += 1; + } + switch (op_) { case '&': // Reduction AND case '|': // Reduction OR @@ -6311,7 +6363,6 @@ unsigned PEUnary::test_width(Design*des, NetScope*scope, width_mode_t&mode) return expr_width_; } - expr_width_ = expr_->test_width(des, scope, mode); expr_type_ = expr_->expr_type(); min_width_ = expr_->min_width(); signed_flag_ = expr_->has_sign(); diff --git a/eval_tree.cc b/eval_tree.cc index 9f89559e7..b9ba7fb39 100644 --- a/eval_tree.cc +++ b/eval_tree.cc @@ -404,7 +404,6 @@ NetEConst* NetEBComp::eval_leeq_(const NetExpr*le, const NetExpr*re) const { if (le->expr_type() == IVL_VT_REAL || re->expr_type() == IVL_VT_REAL) return eval_leeq_real_(le, re, true); -// assert(expr_type() == IVL_VT_LOGIC); const NetEConst*r = dynamic_cast(re); if (r == 0) return 0; @@ -416,12 +415,6 @@ NetEConst* NetEBComp::eval_leeq_(const NetExpr*le, const NetExpr*re) const return res; } - if (le->expr_width() == 0) { - cerr << get_fileline() << ": internal error: Something wrong " - << "with the left side width of <= ?" << endl; - cerr << get_fileline() << ": : " << *this << endl; - } - if (NetEConst*tmp = must_be_leeq_(le, rv, true)) { return tmp; } diff --git a/netmisc.cc b/netmisc.cc index def9f0d6d..78e35a78e 100644 --- a/netmisc.cc +++ b/netmisc.cc @@ -858,6 +858,13 @@ static NetExpr* do_elab_and_eval(Design*des, NetScope*scope, PExpr*pe, pe->test_width(des, scope, mode); + if (pe->expr_type() == IVL_VT_CLASS) { + cerr << pe->get_fileline() << ": Error: " + << "Class/null r-value not allowed in this context." << endl; + des->errors += 1; + return 0; + } + // Get the final expression width. If the expression is unsized, // this may be different from the value returned by test_width(). unsigned expr_width = pe->expr_width(); diff --git a/tgt-vvp/eval_vec4.c b/tgt-vvp/eval_vec4.c index 278f8fda5..ae9dba47d 100644 --- a/tgt-vvp/eval_vec4.c +++ b/tgt-vvp/eval_vec4.c @@ -1398,10 +1398,21 @@ void draw_eval_vec4(ivl_expr_t expr) draw_property_vec4(expr); return; + case IVL_EX_NULL: + fprintf(stderr, "%s:%u: Error: 'null' used in an expression\n", + ivl_expr_file(expr), ivl_expr_lineno(expr)); + fprintf(vvp_out, "; Error 'null' used in an expression\n"); + vvp_errors += 1; + return; + default: break; } - fprintf(stderr, "XXXX Evaluate VEC4 expression (%d)\n", ivl_expr_type(expr)); - fprintf(vvp_out, "; XXXX Evaluate VEC4 expression (%d)\n", ivl_expr_type(expr)); + fprintf(stderr, "%s:%u: Sorry: cannot evaluate VEC4 expression (%d)\n", + ivl_expr_file(expr), ivl_expr_lineno(expr), + ivl_expr_type(expr)); + fprintf(vvp_out, "; Sorry: cannot evaluate VEC4 expression (%d)\n", + ivl_expr_type(expr)); + vvp_errors += 1; }