Fixed access-after-delete bug in mem2reg code

This commit is contained in:
Clifford Wolf 2016-05-27 17:25:33 +02:00
parent e9ceec26ff
commit ee071586c5
2 changed files with 23 additions and 6 deletions

View File

@ -219,6 +219,7 @@ namespace AST
dict<AstNode*, uint32_t> &mem2reg_flags, dict<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
bool mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block);
bool mem2reg_check(pool<AstNode*> &mem2reg_set);
void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);
void meminfo(int &mem_width, int &mem_size, int &addr_bits);
// additional functionality for evaluating constant functions

View File

@ -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<AstNode*> 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<AstNode*> &mem2reg_set)
return true;
}
void AstNode::mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &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<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block)
{