From efc3bbd29e35bd2b308de1456d0611a1d1af276c Mon Sep 17 00:00:00 2001 From: Cary R Date: Wed, 1 Apr 2009 18:31:29 -0700 Subject: [PATCH] Report an error when trying to take the select of a real value. This patch adds checks in various places to prevent the user from taking a select of a real value (bit, part and indexed selects). (cherry picked from commit 5852f1eb7a28caf3207b043c6dff738bdbbff0b3) --- elab_expr.cc | 24 ++++++++++++++++++++++++ elab_lval.cc | 17 +++++++++++++++++ elab_net.cc | 15 +++++++++++++++ elaborate.cc | 4 +++- 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/elab_expr.cc b/elab_expr.cc index 0e93a2898..397dafd3d 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -2354,6 +2354,14 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des, if (!name_tail.index.empty()) use_sel = name_tail.index.back().sel; + if (par->expr_type() == IVL_VT_REAL && + use_sel != index_component_t::SEL_NONE) { + cerr << get_fileline() << ": error: " + << "Can not select part of a real parameter value." << endl; + des->errors += 1; + return 0; + } + // NOTE TO SELF: This is the way I want to see this code // structured. This closely follows the structure of the // elaborate_expr_net_ code, which splits all the various @@ -2626,6 +2634,14 @@ NetExpr* PEIdent::elaborate_expr_net_word_(Design*des, NetScope*scope, if (name_tail.index.size() > 1) word_sel = name_tail.index.back().sel; + if (res->expr_type() == IVL_VT_REAL && + word_sel != index_component_t::SEL_NONE) { + cerr << get_fileline() << ": error: " + << "Can not select part of a real array word." << endl; + des->errors += 1; + return 0; + } + if (word_sel == index_component_t::SEL_PART) return elaborate_expr_net_part_(des, scope, res, found_in); @@ -2920,6 +2936,14 @@ NetExpr* PEIdent::elaborate_expr_net(Design*des, NetScope*scope, if (! path_.back().index.empty()) use_sel = path_.back().index.back().sel; + if (node->expr_type() == IVL_VT_REAL && + use_sel != index_component_t::SEL_NONE) { + cerr << get_fileline() << ": error: " + << "Can not select part of a real value." << endl; + des->errors += 1; + return 0; + } + // If this is a part select of a signal, then make a new // temporary signal that is connected to just the // selected bits. The lsb_ and msb_ expressions are from diff --git a/elab_lval.cc b/elab_lval.cc index dcfef023a..b20a2f2e2 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -195,6 +195,15 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, if (reg->array_dimensions() > 0) return elaborate_lval_net_word_(des, scope, reg); + // This must be after the array word elaboration above! + if (reg->data_type() == IVL_VT_REAL && + use_sel != index_component_t::SEL_NONE) { + cerr << get_fileline() << ": error: " + << "Can not select part of a real value." << endl; + des->errors += 1; + return 0; + } + if (use_sel == index_component_t::SEL_PART) { NetAssign_*lv = new NetAssign_(reg); elaborate_lval_net_part_(des, scope, lv); @@ -289,6 +298,14 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des, if (name_tail.index.size() > 1) use_sel = name_tail.index.back().sel; + if (reg->data_type() == IVL_VT_REAL && + use_sel != index_component_t::SEL_NONE) { + cerr << get_fileline() << ": error: " + << "Can not select part of a real array word." << endl; + des->errors += 1; + return 0; + } + if (use_sel == index_component_t::SEL_BIT) elaborate_lval_net_bit_(des, scope, lv); diff --git a/elab_net.cc b/elab_net.cc index 1f4ea2c29..499eb464d 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -460,6 +460,14 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, /* The array has a part/bit select at the end. */ if (name_tail.index.size() > sig->array_dimensions()) { + if (sig->data_type() == IVL_VT_REAL) { + cerr << get_fileline() << ": error: " + << "Can not select part of a real array word." + << endl; + des->errors += 1; + return 0; + } + long midx_tmp, lidx_tmp; if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp)) return 0; @@ -475,6 +483,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, lidx = lidx_tmp; } } else if (!name_tail.index.empty()) { + if (sig->data_type() == IVL_VT_REAL) { + cerr << get_fileline() << ": error: " + << "Can not select part of a real value." << endl; + des->errors += 1; + return 0; + } + long midx_tmp, lidx_tmp; if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp)) return 0; diff --git a/elaborate.cc b/elaborate.cc index 8eec12756..10e7acf4b 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -625,7 +625,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const return; } lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope); - ivl_assert(*this, lval_sigs[idx]); + // The only way this should return zero is if an error + // happened, so for that case just return. + if (lval_sigs[idx] == 0) return; // For now, assume all the outputs are the same width. ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width());