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:
Cary R 2009-09-25 17:23:53 -07:00 committed by Stephen Williams
parent 996424a7be
commit 3259354d29
2 changed files with 6 additions and 19 deletions

View File

@ -183,7 +183,6 @@ class PEConcat : public PExpr {
std::valarray<unsigned>tested_widths_;
PExpr*repeat_;
NetExpr*repeat_expr_;
};
/*

View File

@ -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);
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;
}
need_constant_expr = true;
NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1);
need_constant_expr = false;
assert(tmp);
if (tmp->expr_type() == IVL_VT_REAL) {
cerr << tmp->get_fileline() << ": error: Concatenation "