The concat object can get out of sequence so don't optimize a repeat.
Under some situation the optimized repeat expression can get out of sync while it is being processed this causes the code to reference freed memory. This happens when the repeat expression is converted to an unsigned integer, but the repeat expression is used in a different path. It was easier to just remove the optimization then track down the convoluted call sequence that was causing this and then figure out what needed to be fixed. The repeat expression must be constant, so is likely not too complicated so this optimization is very minor and should not be missed.
This commit is contained in:
parent
996424a7be
commit
3259354d29
1
PExpr.h
1
PExpr.h
|
|
@ -183,7 +183,6 @@ class PEConcat : public PExpr {
|
|||
std::valarray<unsigned>tested_widths_;
|
||||
|
||||
PExpr*repeat_;
|
||||
NetExpr*repeat_expr_;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
18
elab_expr.cc
18
elab_expr.cc
|
|
@ -1564,8 +1564,8 @@ unsigned PEConcat::test_width(Design*des, NetScope*scope,
|
|||
// Try to evaluate the repeat expression now, so
|
||||
// that we can give the caller an accurate
|
||||
// expression width.
|
||||
repeat_expr_ = elab_and_eval(des, scope, repeat_, -1);
|
||||
if (NetEConst*tmp_c = dynamic_cast<NetEConst*> (repeat_expr_)) {
|
||||
NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
|
||||
if (NetEConst*tmp_c = dynamic_cast<NetEConst*> (tmp)) {
|
||||
repeat_count = tmp_c->value().as_ulong();
|
||||
|
||||
} else {
|
||||
|
|
@ -1605,22 +1605,10 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
|
|||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count. */
|
||||
if (repeat_) {
|
||||
NetExpr*tmp;
|
||||
if (repeat_expr_ == 0) {
|
||||
// If the expression has not yet been elaborated,
|
||||
// then try now.
|
||||
need_constant_expr = true;
|
||||
tmp = elab_and_eval(des, scope, repeat_, -1);
|
||||
NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
|
||||
need_constant_expr = false;
|
||||
assert(tmp);
|
||||
} else {
|
||||
// If it has been elaborated, make sure it is
|
||||
// fully evaluated.
|
||||
tmp = repeat_expr_;
|
||||
need_constant_expr = true;
|
||||
eval_expr(tmp);
|
||||
need_constant_expr = false;
|
||||
}
|
||||
|
||||
if (tmp->expr_type() == IVL_VT_REAL) {
|
||||
cerr << tmp->get_fileline() << ": error: Concatenation "
|
||||
|
|
|
|||
Loading…
Reference in New Issue