Do not create implicit nets for type identifiers

`PEIdent::declare_implicit_nets()` checks visible nets, parameters, genvars,
events, and enum constants before creating an implicit net, but does not check
typedefs. Type identifiers are currently filtered by the grammar before they
can reach this code, but this is not true when type and hierarchy identifier
parsing use the same path.

Check local and imported typedefs while searching the lexical scopes. Stop the
type search when another local declaration hides an outer typedef.

Signed-off-by: Lars-Peter Clausen <[email protected]>
This commit is contained in:
Lars-Peter Clausen
2026-08-23 11:40:06 -07:00
parent 5726589cac
commit 65b943b009
+27
View File
@@ -25,6 +25,7 @@
# include "compiler.h"
# include "PExpr.h"
# include "PPackage.h"
# include "PWire.h"
# include "Module.h"
# include "ivl_assert.h"
@@ -419,6 +420,29 @@ static bool find_enum_constant(LexicalScope*scope, perm_string name)
});
}
static bool is_typedef_identifier(LexicalScope *scope, perm_string name)
{
while (scope) {
auto import = scope->explicit_imports.find(name);
if (import != scope->explicit_imports.end()) {
// An explicit import shadows declarations in outer scopes.
const auto &typedefs = import->second.package->typedefs;
return typedefs.find(name) != typedefs.end();
}
if (scope->typedefs.find(name) != scope->typedefs.end())
return true;
// A local non-type declaration also hides outer typedefs.
if (scope->local_symbols.find(name) != scope->local_symbols.end())
return false;
scope = scope->parent_scope();
}
return false;
}
void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
{
/* We create an implicit wire if:
@@ -432,6 +456,9 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
return;
if (path_.name.size() == 1 && path_.name.front().index.empty()) {
perm_string name = path_.name.front().name;
if (is_typedef_identifier(scope, name))
return;
LexicalScope*ss = scope;
while (ss) {
if (ss->wires.find(name) != ss->wires.end())