Elaborate array assignment pattern values in the right context
The expressions within an array assignment pattern should be evaluated in a
context that is equivalent to an assignment to a variable of the element
type of the l-value array.
This is defined in section 10.9.1 ("Array assignment patterns") of the LRM
(1800-2017).
At the moment the values in an assignment pattern are evaluated in a self
determined context, which can lead to incorrect behavior.
Use the existing `elaborate_rval_expr()` function, which is meant for
elaborating assignments, to elaborate the assignment pattern values.
This solves the following issues:
* implicit width conversion (including sign extension)
* implicit type conversion (e.g. real to vector)
* math operators that depend on the target width (e.g. addition)
* use of expressions that require `test_width()` to be called. (e.g.
unary operator)
* use of concatenations
* use of named constants (e.g. parameters or enums)
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
parent
f19ba64614
commit
5b8fb089bf
|
|
@ -91,8 +91,8 @@ static NetBranch* find_existing_implicit_branch(NetNet*sig, NetNet*gnd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
NetExpr* elaborate_rval_expr(Design*des, NetScope*scope, ivl_type_t lv_net_type,
|
||||
PExpr*expr, bool need_const, bool force_unsigned)
|
||||
NetExpr* elaborate_rval_expr(Design *des, NetScope *scope, ivl_type_t lv_net_type,
|
||||
PExpr *expr, bool need_const, bool force_unsigned)
|
||||
{
|
||||
return elaborate_rval_expr(des, scope, lv_net_type,
|
||||
lv_net_type->base_type(),
|
||||
|
|
@ -236,13 +236,16 @@ NetExpr*PEAssignPattern::elaborate_expr_darray_(Design*des, NetScope*scope,
|
|||
const netdarray_t*array_type = dynamic_cast<const netdarray_t*> (ntype);
|
||||
ivl_assert(*this, array_type);
|
||||
|
||||
bool need_const = NEED_CONST & flags;
|
||||
|
||||
// This is an array pattern, so run through the elements of
|
||||
// the expression and elaborate each as if they are
|
||||
// element_type expressions.
|
||||
ivl_type_t elem_type = array_type->element_type();
|
||||
vector<NetExpr*> elem_exprs (parms_.size());
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
NetExpr*tmp = parms_[idx]->elaborate_expr(des, scope, elem_type, flags);
|
||||
NetExpr*tmp = elaborate_rval_expr(des, scope, elem_type,
|
||||
parms_[idx], need_const);
|
||||
elem_exprs[idx] = tmp;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -411,8 +411,8 @@ extern NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
|
|||
/*
|
||||
* Same as above, but lv_width and lv_type are derived from the lv_net_type.
|
||||
*/
|
||||
extern NetExpr* elaborate_rval_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t lv_net_type, PExpr*expr,
|
||||
extern NetExpr* elaborate_rval_expr(Design *des, NetScope *scope,
|
||||
ivl_type_t lv_net_type, PExpr *expr,
|
||||
bool need_const = false,
|
||||
bool force_unsigned = false);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue