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 5852f1eb7a)
This commit is contained in:
parent
c56f21a20c
commit
efc3bbd29e
24
elab_expr.cc
24
elab_expr.cc
|
|
@ -2354,6 +2354,14 @@ NetExpr* PEIdent::elaborate_expr_param_(Design*des,
|
||||||
if (!name_tail.index.empty())
|
if (!name_tail.index.empty())
|
||||||
use_sel = name_tail.index.back().sel;
|
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
|
// NOTE TO SELF: This is the way I want to see this code
|
||||||
// structured. This closely follows the structure of the
|
// structured. This closely follows the structure of the
|
||||||
// elaborate_expr_net_ code, which splits all the various
|
// 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)
|
if (name_tail.index.size() > 1)
|
||||||
word_sel = name_tail.index.back().sel;
|
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)
|
if (word_sel == index_component_t::SEL_PART)
|
||||||
return elaborate_expr_net_part_(des, scope, res, found_in);
|
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())
|
if (! path_.back().index.empty())
|
||||||
use_sel = path_.back().index.back().sel;
|
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
|
// If this is a part select of a signal, then make a new
|
||||||
// temporary signal that is connected to just the
|
// temporary signal that is connected to just the
|
||||||
// selected bits. The lsb_ and msb_ expressions are from
|
// selected bits. The lsb_ and msb_ expressions are from
|
||||||
|
|
|
||||||
17
elab_lval.cc
17
elab_lval.cc
|
|
@ -195,6 +195,15 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||||
if (reg->array_dimensions() > 0)
|
if (reg->array_dimensions() > 0)
|
||||||
return elaborate_lval_net_word_(des, scope, reg);
|
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) {
|
if (use_sel == index_component_t::SEL_PART) {
|
||||||
NetAssign_*lv = new NetAssign_(reg);
|
NetAssign_*lv = new NetAssign_(reg);
|
||||||
elaborate_lval_net_part_(des, scope, lv);
|
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)
|
if (name_tail.index.size() > 1)
|
||||||
use_sel = name_tail.index.back().sel;
|
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)
|
if (use_sel == index_component_t::SEL_BIT)
|
||||||
elaborate_lval_net_bit_(des, scope, lv);
|
elaborate_lval_net_bit_(des, scope, lv);
|
||||||
|
|
||||||
|
|
|
||||||
15
elab_net.cc
15
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. */
|
/* The array has a part/bit select at the end. */
|
||||||
if (name_tail.index.size() > sig->array_dimensions()) {
|
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;
|
long midx_tmp, lidx_tmp;
|
||||||
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
|
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -475,6 +483,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||||
lidx = lidx_tmp;
|
lidx = lidx_tmp;
|
||||||
}
|
}
|
||||||
} else if (!name_tail.index.empty()) {
|
} 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;
|
long midx_tmp, lidx_tmp;
|
||||||
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
|
if (! eval_part_select_(des, scope, sig, midx_tmp, lidx_tmp))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -625,7 +625,9 @@ void PGBuiltin::elaborate(Design*des, NetScope*scope) const
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lval_sigs[idx] = pin(idx)->elaborate_lnet(des, scope);
|
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.
|
// 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());
|
ivl_assert(*this, idx == 0 || lval_sigs[idx]->vector_width() == lval_sigs[0]->vector_width());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue