From e8dada7337d97d53e26306ed2bfe84174bec8fa6 Mon Sep 17 00:00:00 2001 From: Cary R Date: Fri, 25 Sep 2009 17:23:53 -0700 Subject: [PATCH] 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. (cherry picked from commit 3259354d293d224108bb61a5d5827deca48c4d7f) --- PExpr.h | 1 - elab_expr.cc | 24 ++++++------------------ 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/PExpr.h b/PExpr.h index 00c3c2fee..791e68bbd 100644 --- a/PExpr.h +++ b/PExpr.h @@ -183,7 +183,6 @@ class PEConcat : public PExpr { std::valarraytested_widths_; PExpr*repeat_; - NetExpr*repeat_expr_; }; /* diff --git a/elab_expr.cc b/elab_expr.cc index 89698a49a..5d4f30bba 100644 --- a/elab_expr.cc +++ b/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 (repeat_expr_)) { + NetExpr*tmp = elab_and_eval(des, scope, repeat_, -1); + if (NetEConst*tmp_c = dynamic_cast (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 "