sv: fix up end label checking

- disallow [gen]blocks with an end label but not begin label
- check validity of module end label
- fix memory leak of package name and end label
- fix memory leak of module end label
This commit is contained in:
Zachary Snow 2021-06-14 15:32:01 -04:00 committed by Zachary Snow
parent 092f0cb01e
commit f2c2d73f36
7 changed files with 98 additions and 7 deletions

View File

@ -235,6 +235,16 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
node->children.push_back(rangeNode); node->children.push_back(rangeNode);
} }
static void checkLabelsMatch(const char *element, const std::string *before, const std::string *after)
{
if (!before && after)
frontend_verilog_yyerror("%s missing where end label (%s) was given.",
element, after->c_str() + 1);
if (before && after && *before != *after)
frontend_verilog_yyerror("%s (%s) and end label (%s) don't match.",
element, before->c_str() + 1, after->c_str() + 1);
}
%} %}
%define api.prefix {frontend_verilog_yy} %define api.prefix {frontend_verilog_yy}
@ -457,7 +467,6 @@ module:
port_counter = 0; port_counter = 0;
mod->str = *$4; mod->str = *$4;
append_attr(mod, $1); append_attr(mod, $1);
delete $4;
} module_para_opt module_args_opt ';' module_body TOK_ENDMODULE opt_label { } module_para_opt module_args_opt ';' module_body TOK_ENDMODULE opt_label {
if (port_stubs.size() != 0) if (port_stubs.size() != 0)
frontend_verilog_yyerror("Missing details for module port `%s'.", frontend_verilog_yyerror("Missing details for module port `%s'.",
@ -465,7 +474,10 @@ module:
SET_AST_NODE_LOC(ast_stack.back(), @2, @$); SET_AST_NODE_LOC(ast_stack.back(), @2, @$);
ast_stack.pop_back(); ast_stack.pop_back();
log_assert(ast_stack.size() == 1); log_assert(ast_stack.size() == 1);
checkLabelsMatch("Module name", $4, $11);
current_ast_mod = NULL; current_ast_mod = NULL;
delete $4;
delete $11;
exitTypeScope(); exitTypeScope();
}; };
@ -583,9 +595,10 @@ package:
append_attr(mod, $1); append_attr(mod, $1);
} ';' package_body TOK_ENDPACKAGE opt_label { } ';' package_body TOK_ENDPACKAGE opt_label {
ast_stack.pop_back(); ast_stack.pop_back();
if ($4 != NULL && $9 != NULL && *$4 != *$9) checkLabelsMatch("Package name", $4, $9);
frontend_verilog_yyerror("Package name (%s) and end label (%s) don't match.", $4->c_str()+1, $9->c_str()+1);
current_ast_mod = NULL; current_ast_mod = NULL;
delete $4;
delete $9;
exitTypeScope(); exitTypeScope();
}; };
@ -2526,8 +2539,7 @@ behavioral_stmt:
node->str = *$4; node->str = *$4;
} behavioral_stmt_list TOK_END opt_label { } behavioral_stmt_list TOK_END opt_label {
exitTypeScope(); exitTypeScope();
if ($4 != NULL && $8 != NULL && *$4 != *$8) checkLabelsMatch("Begin label", $4, $8);
frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $4->c_str()+1, $8->c_str()+1);
AstNode *node = ast_stack.back(); AstNode *node = ast_stack.back();
// In SystemVerilog, unnamed blocks with block item declarations // In SystemVerilog, unnamed blocks with block item declarations
// create an implicit hierarchy scope // create an implicit hierarchy scope
@ -2863,8 +2875,7 @@ gen_block:
ast_stack.push_back(node); ast_stack.push_back(node);
} module_gen_body TOK_END opt_label { } module_gen_body TOK_END opt_label {
exitTypeScope(); exitTypeScope();
if ($3 != NULL && $7 != NULL && *$3 != *$7) checkLabelsMatch("Begin label", $3, $7);
frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $3->c_str()+1, $7->c_str()+1);
delete $3; delete $3;
delete $7; delete $7;
SET_AST_NODE_LOC(ast_stack.back(), @1, @7); SET_AST_NODE_LOC(ast_stack.back(), @1, @7);

View File

@ -0,0 +1,29 @@
module top(
output reg [7:0]
out1, out2, out3, out4
);
initial begin
begin : blk1
reg x;
x = 1;
end
out1 = blk1.x;
begin : blk2
reg x;
x = 2;
end : blk2
out2 = blk2.x;
end
if (1) begin
if (1) begin : blk3
reg x;
assign x = 3;
end
assign out3 = blk3.x;
if (1) begin : blk4
reg x;
assign x = 4;
end : blk4
assign out4 = blk4.x;
end
endmodule

View File

@ -0,0 +1,9 @@
logger -expect error "Begin label missing where end label \(incorrect_name\) was given\." 1
read_verilog -sv <<EOF
module top;
initial
begin
$display("HI");
end : incorrect_name
endmodule
EOF

View File

@ -0,0 +1,9 @@
logger -expect error "Begin label \(correct_name\) and end label \(incorrect_name\) don't match\." 1
read_verilog -sv <<EOF
module top;
initial
begin : correct_name
$display("HI");
end : incorrect_name
endmodule
EOF

View File

@ -0,0 +1,9 @@
logger -expect error "Begin label missing where end label \(incorrect_name\) was given\." 1
read_verilog -sv <<EOF
module top;
if (1)
begin
initial $display("HI");
end : incorrect_name
endmodule
EOF

View File

@ -0,0 +1,9 @@
logger -expect error "Begin label \(correct_name\) and end label \(incorrect_name\) don't match\." 1
read_verilog -sv <<EOF
module top;
if (1)
begin : correct_name
initial $display("HI");
end : incorrect_name
endmodule
EOF

View File

@ -0,0 +1,15 @@
logger -expect-no-warnings
read_verilog -sv <<EOF
module correct_name;
localparam X = 1;
endmodule : correct_name
EOF
design -reset
logger -expect error "Module name \(correct_name\) and end label \(incorrect_name\) don't match\." 1
read_verilog -sv <<EOF
module correct_name;
localparam X = 1;
endmodule : incorrect_name
EOF