From 8f18f0cf225245eb7fc380957e4f06d65e46e44c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 28 Apr 2026 17:59:18 -0400 Subject: [PATCH] Fix internal error instead of missing prototype error (#7485). [Alex Solomatnikov] Fixes #7485. --- Changes | 1 + src/V3LinkDot.cpp | 1 + src/V3SymTable.h | 11 ++++++++++- test_regress/t/t_class_extern_mis2_bad.out | 5 +++++ test_regress/t/t_class_extern_mis2_bad.py | 16 ++++++++++++++++ test_regress/t/t_class_extern_mis2_bad.v | 21 +++++++++++++++++++++ 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 test_regress/t/t_class_extern_mis2_bad.out create mode 100755 test_regress/t/t_class_extern_mis2_bad.py create mode 100644 test_regress/t/t_class_extern_mis2_bad.v diff --git a/Changes b/Changes index 6ad820bff..6f3f2c62c 100644 --- a/Changes +++ b/Changes @@ -17,6 +17,7 @@ Verilator 5.049 devel * Fix inlining static initializer in V3Gate (#5381) (#7503). [Andrew Nolte] [Geza Lore, Testorrent USA, Inc.] * Fix generic interface port forwarded to a nested instance (#7454) (#7457). [Yilou Wang] * Fix internal error on multi-cycle SVA under default clocking (#7472) (#7506). [Yilou Wang] +* Fix internal error instead of missing prototype error (#7485). [Alex Solomatnikov] * Fix mailbox#(packed_struct) type mismatch with parameterized class (#7494) (#7495). [Nikolai Kumar] * Fix std::randomize internal error on static member of different class (#7498) (#7499). [Alex Solomatnikov] * Fix virtual interface method call inlining and IMPURE suppression (#7505). [Nikolay Puzanov] diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 758352a7f..66b9abcc6 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -193,6 +193,7 @@ public: void dumpSelf(const string& nameComment, bool force = false) { if (debug() >= 6 || dumpLevel() >= 6 || force) { const string filename = v3Global.debugFilename(nameComment) + ".txt"; + UINFO(4, "Dumping " << filename); const std::unique_ptr logp{V3File::new_ofstream(filename)}; if (logp->fail()) v3fatal("Can't write file: " << filename); std::ostream& os = *logp; diff --git a/src/V3SymTable.h b/src/V3SymTable.h index dbb5b383d..f3cb1bfb1 100644 --- a/src/V3SymTable.h +++ b/src/V3SymTable.h @@ -207,9 +207,18 @@ public: void importFromClass(VSymGraph* graphp, const VSymEnt* srcp) { // Import tokens from source symbol table into this symbol table // Used for classes in early parsing only to handle "extends" + + // If an "extern foo" exists, then we can't import "foo" from the base class. + // But ok for "extern foo" and "foo" to both come from base (so must check before insert) + std::unordered_set haveExterns; for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin(); it != srcp->m_idNameMap.end(); ++it) { - importOneSymbol(graphp, it->first, it->second, false); + if (m_idNameMap.count("extern " + it->first)) haveExterns.emplace(it->first); + } + for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin(); + it != srcp->m_idNameMap.end(); ++it) { + if (!haveExterns.count(it->first)) + importOneSymbol(graphp, it->first, it->second, false); } } void importFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) { diff --git a/test_regress/t/t_class_extern_mis2_bad.out b/test_regress/t/t_class_extern_mis2_bad.out new file mode 100644 index 000000000..2382ded8b --- /dev/null +++ b/test_regress/t/t_class_extern_mis2_bad.out @@ -0,0 +1,5 @@ +%Error-PROTOTYPEMIS: t/t_class_extern_mis2_bad.v:15:21: Definition not found for extern prototype 'new' + 15 | extern function new(); + | ^~~ + ... For error description see https://verilator.org/warn/PROTOTYPEMIS?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_class_extern_mis2_bad.py b/test_regress/t/t_class_extern_mis2_bad.py new file mode 100755 index 000000000..38cf36b43 --- /dev/null +++ b/test_regress/t/t_class_extern_mis2_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of either the GNU Lesser General Public License Version 3 +# or the Perl Artistic License Version 2.0. +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_class_extern_mis2_bad.v b/test_regress/t/t_class_extern_mis2_bad.v new file mode 100644 index 000000000..a7985be14 --- /dev/null +++ b/test_regress/t/t_class_extern_mis2_bad.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 Wilson Snyder +// SPDX-License-Identifier: CC0-1.0 + +package s_core_env_pkg; + virtual class x_scoreboard; + extern function void has_ext_ok(); + endclass + function void x_scoreboard::has_ext_ok(); + endfunction + + class cls_misses_new_1 extends x_scoreboard; + extern function new(); // <--- BAD + endclass + +endpackage + +module t; +endmodule