From 6730ead11942917cb898bde2ed317f42132b9941 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 3 Feb 2022 10:48:42 +0100 Subject: [PATCH] Generate error for invalid declarations within generate block Most things that can be declared in a module can also be declared in a generate block. But there are a few exceptions that can not be declared in generate block * module, program or interface declaration * specify block or specparam * timeunit Some of these currently work while some of them trigger an assertion and cause and application crash. Add checks to make sure that all of them these are reported as an error and do not cause a crash. Signed-off-by: Lars-Peter Clausen --- parse.y | 26 +++++++++++++++++++++----- pform.cc | 21 ++++++++++++++++++--- pform.h | 2 ++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/parse.y b/parse.y index 64fe44da7..8af33f0b9 100644 --- a/parse.y +++ b/parse.y @@ -4868,10 +4868,22 @@ module keyword. The syntax for modules programs, and interfaces is almost identical, so let semantics sort out the differences. */ module_start - : K_module { $$ = K_module; } - | K_macromodule { $$ = K_module; } - | K_program { $$ = K_program; } - | K_interface { $$ = K_interface; } + : K_module + { pform_error_in_generate(@1, "module declaration"); + $$ = K_module; + } + | K_macromodule + { pform_error_in_generate(@1, "module declaration"); + $$ = K_module; + } + | K_program + { pform_error_in_generate(@1, "program declaration"); + $$ = K_program; + } + | K_interface + { pform_error_in_generate(@1, "interface declaration"); + $$ = K_interface; + } ; module_end @@ -5262,6 +5274,7 @@ module_item | attribute_list_opt assertion_item | timeunits_declaration + { pform_error_in_generate(@1, "timeunit declaration"); } | class_declaration @@ -5330,8 +5343,9 @@ module_item | attribute_list_opt K_specparam { if (pform_in_interface()) - yyerror(@1, "error: specparam declarations are not allowed " + yyerror(@2, "error: specparam declarations are not allowed " "in interfaces."); + pform_error_in_generate(@2, "specparam declaration"); } specparam_decl ';' @@ -5341,7 +5355,9 @@ module_item { if (pform_in_interface()) yyerror(@1, "error: specify blocks are not allowed " "in interfaces."); + pform_error_in_generate(@1, "specify block"); } + specify_item_list_opt K_endspecify | K_specify error K_endspecify diff --git a/pform.cc b/pform.cc index dd171773c..157231a69 100644 --- a/pform.cc +++ b/pform.cc @@ -780,6 +780,15 @@ PGenerate* pform_parent_generate(void) return pform_cur_generate; } +bool pform_error_in_generate(const vlltype&loc, const char *type) +{ + if (!pform_parent_generate()) + return false; + + VLerror(loc, "error: %s is not allowed in generate block.", type); + return true; +} + void pform_bind_attributes(map&attributes, list*attr, bool keep_attrs) { @@ -1212,7 +1221,8 @@ void pform_set_timeunit(const char*txt, bool initial_decl) if (get_time_unit_prec(txt, val, true)) return; PScopeExtra*scope = dynamic_cast(lexical_scope); - assert(scope); + if (!scope) + return; if (initial_decl) { scope->time_unit = val; @@ -1249,7 +1259,8 @@ void pform_set_timeprec(const char*txt, bool initial_decl) if (get_time_unit_prec(txt, val, false)) return; PScopeExtra*scope = dynamic_cast(lexical_scope); - assert(scope); + if (!scope) + return; if (initial_decl) { scope->time_precision = val; @@ -3288,7 +3299,11 @@ void pform_set_specparam(const struct vlltype&loc, perm_string name, { assert(! pform_cur_module.empty()); Module*scope = pform_cur_module.front(); - assert(scope == lexical_scope); + if (scope != lexical_scope) { + delete range; + delete expr; + return; + } assert(expr); Module::param_expr_t*parm = new Module::param_expr_t(); diff --git a/pform.h b/pform.h index 52199eaad..861d59e67 100644 --- a/pform.h +++ b/pform.h @@ -323,6 +323,8 @@ extern void pform_endgenerate(bool end_conditional); */ extern PGenerate* pform_parent_generate(void); +bool pform_error_in_generate(const vlltype&loc, const char *type); + extern void pform_make_elab_task(const struct vlltype&li, perm_string name, const std::list¶ms);