From 78b21907c6b25418107c1bd7e337c11d05c7798b Mon Sep 17 00:00:00 2001 From: Daniel Kroening Date: Tue, 3 Mar 2026 19:34:45 +0000 Subject: [PATCH] SystemVerilog: detect import conflicts Per IEEE 1800-2017 section 26.3, this adds error detection for: - Direct imports that conflict with local declarations - Wildcard imports that are used in expressions and then redeclared Wildcard imports that are not used remain 'potentially locally visible' and can be shadowed by local declarations. --- regression/verilog/packages/import6.desc | 4 ++-- regression/verilog/packages/import8.desc | 2 +- src/verilog/verilog_scope.cpp | 18 ++++++++++++++++++ src/verilog/verilog_scope.h | 7 +------ 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/regression/verilog/packages/import6.desc b/regression/verilog/packages/import6.desc index bcb0df282..cf9c2675d 100644 --- a/regression/verilog/packages/import6.desc +++ b/regression/verilog/packages/import6.desc @@ -1,7 +1,7 @@ -KNOWNBUG +CORE import6.sv --bound 0 -^EXIT=2$ +^EXIT=6$ ^SIGNAL=0$ -- -- diff --git a/regression/verilog/packages/import8.desc b/regression/verilog/packages/import8.desc index 16e116fcb..0313a744c 100644 --- a/regression/verilog/packages/import8.desc +++ b/regression/verilog/packages/import8.desc @@ -1,7 +1,7 @@ KNOWNBUG import8.sv --bound 0 -^EXIT=2$ +^EXIT=6$ ^SIGNAL=0$ -- -- diff --git a/src/verilog/verilog_scope.cpp b/src/verilog/verilog_scope.cpp index fc63e4429..11a4b5130 100644 --- a/src/verilog/verilog_scope.cpp +++ b/src/verilog/verilog_scope.cpp @@ -51,6 +51,16 @@ const verilog_scopet *verilog_scopest::lookup(irep_idt base_name) const return nullptr; } +verilog_scopet &verilog_scopest::add_name( + irep_idt _base_name, + const std::string &separator, + scopet::kindt kind) +{ + auto result = current_scope().scope_map.emplace( + _base_name, scopet{_base_name, separator, ¤t_scope(), kind}); + return result.first->second; +} + void verilog_scopet::print_rec(std::size_t indent, std::ostream &out) const { out << std::string(indent, ' ') << prefix << '\n'; @@ -96,6 +106,14 @@ void verilog_scopest::import(irep_idt package, irep_idt base_name) auto name_it = package_it->second.scope_map.find(base_name); if(name_it != package_it->second.scope_map.end()) { + // Check if the identifier already exists in the current scope + auto existing = current_scope().scope_map.find(base_name); + if(existing != current_scope().scope_map.end()) + { + throw typecheckt::errort().with_location(source_locationt()) + << "identifier '" << base_name + << "' conflicts with earlier declaration"; + } auto &scope = add_name(base_name, "", name_it->second.kind); scope.import = name_it->second.identifier(); } diff --git a/src/verilog/verilog_scope.h b/src/verilog/verilog_scope.h index 076957a92..23ebf712e 100644 --- a/src/verilog/verilog_scope.h +++ b/src/verilog/verilog_scope.h @@ -100,12 +100,7 @@ class verilog_scopest scopet &add_name( irep_idt _base_name, const std::string &separator, - scopet::kindt kind) - { - auto result = current_scope().scope_map.emplace( - _base_name, scopet{_base_name, separator, ¤t_scope(), kind}); - return result.first->second; - } + scopet::kindt kind); // Scope stack std::vector scope_stack = {&top_scope};