diff --git a/Changes b/Changes index 7dc8d7e66..f70355566 100644 --- a/Changes +++ b/Changes @@ -31,6 +31,7 @@ Verilator 5.015 devel * Fix internal error on real conversion (#4447). [vdhotre-ventana] * Fix lifetime unknown error on enum.name (#4448). [jwoutersymatra] * Fix display %x formatting of real. +* Fix mis-warning on #() in classes' own functions. Verilator 5.014 2023-08-06 diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 3a1819911..afec76e4d 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2905,10 +2905,14 @@ private: UINFO(4, "(Backto) Link ClassOrPackageRef: " << nodep << endl); iterateChildren(nodep); } - if (m_statep->forPrimary() && VN_IS(nodep->classOrPackagep(), Class) && !nodep->paramsp() + AstClass* const refClassp = VN_CAST(nodep->classOrPackagep(), Class); + AstClass* const modClassp = VN_CAST(m_modp, Class); + if (m_statep->forPrimary() && refClassp && !nodep->paramsp() && nodep->classOrPackagep()->hasGParam() // Don't warn on typedefs, which are hard to know if there's a param somewhere buried - && VN_IS(nodep->classOrPackageNodep(), Class)) { + && VN_IS(nodep->classOrPackageNodep(), Class) + // References to class:: within class itself are OK per IEEE (UVM does this) + && modClassp != refClassp) { nodep->v3error("Reference to parameterized class without #() (IEEE 1800-2017 8.25.1)\n" << nodep->warnMore() << "... Suggest use '" << nodep->classOrPackageNodep()->prettyName() << "#()'"); diff --git a/test_regress/t/t_class_new_noparen.pl b/test_regress/t/t_class_new_noparen.pl new file mode 100755 index 000000000..859050d63 --- /dev/null +++ b/test_regress/t/t_class_new_noparen.pl @@ -0,0 +1,21 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2023 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_new_noparen.v b/test_regress/t/t_class_new_noparen.v new file mode 100644 index 000000000..17073677b --- /dev/null +++ b/test_regress/t/t_class_new_noparen.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class u_object; + string m_name; + function new(string name); + m_name = name; + endfunction +endclass + +class u_cache#(type KEY_T=int, type DATA_T=int) extends u_object; + typedef int unsigned size_t; + int m_max_size; + + extern function new(string name="u_cache", size_t max_size = 256); +endclass + +// #() not required below, see IEEE 1800-2017 8.25.1 +function u_cache::new(string name="u_cache", u_cache::size_t max_size = 256); + super.new(name); + this.m_max_size = max_size; +endfunction + +module t(/*AUTOARG*/); + + u_cache #(real, real) obj; + + initial begin + obj = new("fred", 62); + if (obj.m_name != "fred") $stop; + if (obj.m_max_size != 62) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule