diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index fcc91adfc..e8f964ebf 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -1612,7 +1612,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) if (left_at_zero_ast->type != AST_CONSTANT || right_at_zero_ast->type != AST_CONSTANT) input_error("Unsupported expression on dynamic range select on signal `%s'!\n", str.c_str()); int width = abs(int(left_at_zero_ast->integer - right_at_zero_ast->integer)) + 1; - auto fake_ast = new AstNode(AST_NONE, clone(), children[0]->children.size() >= 2 ? + auto fake_ast = std::make_unique(AST_NONE, clone(), children[0]->children.size() >= 2 ? children[0]->children[1]->clone() : children[0]->children[0]->clone()); fake_ast->children[0]->delete_children(); if (member_node) @@ -1633,7 +1633,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) } if (GetSize(shift_val) >= 32) fake_ast->children[1]->is_signed = true; - RTLIL::SigSpec sig = binop2rtlil(fake_ast, ID($shiftx), width, fake_ast->children[0]->genRTLIL(), shift_val); + RTLIL::SigSpec sig = binop2rtlil(fake_ast.get(), ID($shiftx), width, fake_ast->children[0]->genRTLIL(), shift_val); return sig; } else { chunk.width = children[0]->range_left - children[0]->range_right + 1; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index d306c6022..86c5efb6d 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1505,7 +1505,7 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin if (children[0]->type == AST_WIRE) { int width = 1; std::unique_ptr node; - AstNode* child = children[0].release(); + AstNode* child = children[0].get(); if (child->children.size() == 0) { // Base type (e.g., int) width = child->range_left - child->range_right +1; diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index e32446f69..7233d52b5 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -2844,6 +2844,7 @@ behavioral_stmt: std::unique_ptr node_owned; AstNode* node = nullptr; AstNode *context = extra->ast_stack.back(); + bool patch_block_on_stack = false; if (context && context->type == AST_BLOCK && context->get_bool_attribute(ID::promoted_if)) { AstNode *outer = extra->ast_stack[extra->ast_stack.size() - 2]; log_assert (outer && outer->type == AST_CASE); @@ -2852,6 +2853,9 @@ behavioral_stmt: node = outer; log_assert (node->children.size()); node->children.pop_back(); + // `context` has been killed as a grandchild of `outer` + // we have to undangle it from the stack + patch_block_on_stack = true; } else if (outer->get_bool_attribute(ID::full_case)) (*$1)[ID::full_case] = AstNode::mkconst_int(1, false); } @@ -2863,12 +2867,17 @@ behavioral_stmt: append_attr(node, $1); node->children.push_back(node->get_bool_attribute(ID::parallel_case) ? AstNode::mkconst_int(1, false, 1) : expr->clone()); extra->ast_stack.back()->children.push_back(std::move(node_owned)); + } else { + free_attr($1); } auto block_owned = std::make_unique(AST_BLOCK); auto* block = block_owned.get(); auto cond_owned = std::make_unique(AST_COND, node->get_bool_attribute(ID::parallel_case) ? std::move(expr) : AstNode::mkconst_int(1, false, 1), std::move(block_owned)); SET_AST_NODE_LOC(cond_owned.get(), @4, @4); node->children.push_back(std::move(cond_owned)); + // Double it and give it to the next person + if (patch_block_on_stack) + extra->ast_stack.back() = block; extra->ast_stack.push_back(node); extra->ast_stack.push_back(block); } behavioral_stmt {