From: Clifford Wolf Date: Fri, 27 May 2016 15:25:33 +0000 (+0200) Subject: Fixed access-after-delete bug in mem2reg code X-Git-Tag: yosys-0.7~211 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ee071586c55915c6535bad0a47bf80c8f2029272;p=yosys.git Fixed access-after-delete bug in mem2reg code --- diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index b4e58d79f..21c3ba3c6 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -219,6 +219,7 @@ namespace AST dict &mem2reg_flags, dict &proc_flags, uint32_t &status_flags); bool mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, AstNode *block); bool mem2reg_check(pool &mem2reg_set); + void mem2reg_remove(pool &mem2reg_set, vector &delnodes); void meminfo(int &mem_width, int &mem_size, int &addr_bits); // additional functionality for evaluating constant functions diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e00087280..c09b912c2 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -150,12 +150,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, while (mem2reg_as_needed_pass2(mem2reg_set, this, NULL)) { } - for (size_t i = 0; i < children.size(); i++) { - if (mem2reg_set.count(children[i]) > 0) { - delete children[i]; - children.erase(children.begin() + (i--)); - } - } + vector delnodes; + mem2reg_remove(mem2reg_set, delnodes); + + for (auto node : delnodes) + delete node; } while (simplify(const_fold, at_zero, in_lvalue, 2, width_hint, sign_hint, in_param)) { } @@ -2606,6 +2605,23 @@ bool AstNode::mem2reg_check(pool &mem2reg_set) return true; } +void AstNode::mem2reg_remove(pool &mem2reg_set, vector &delnodes) +{ + log_assert(mem2reg_set.count(this) == 0); + + if (mem2reg_set.count(id2ast)) + id2ast = nullptr; + + for (size_t i = 0; i < children.size(); i++) { + if (mem2reg_set.count(children[i]) > 0) { + delnodes.push_back(children[i]); + children.erase(children.begin() + (i--)); + } else { + children[i]->mem2reg_remove(mem2reg_set, delnodes); + } + } +} + // actually replace memories with registers bool AstNode::mem2reg_as_needed_pass2(pool &mem2reg_set, AstNode *mod, AstNode *block) {