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 <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2022-02-03 10:48:42 +01:00
parent 96a1cbf7b2
commit 6730ead119
3 changed files with 41 additions and 8 deletions

26
parse.y
View File

@ -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

View File

@ -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<perm_string,PExpr*>&attributes,
list<named_pexpr_t>*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<PScopeExtra*>(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<PScopeExtra*>(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();

View File

@ -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<PExpr*>&params);