diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 0d5d98796..39ef36202 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -45,6 +45,7 @@ HungMingWu HyungKi Jeong Iru Cai Ivan Vnučec +Ilya Barkov Iztok Jeras Jake Merdich James Hanlon diff --git a/src/V3Width.cpp b/src/V3Width.cpp index fbc73703d..65131acfd 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -3626,6 +3626,10 @@ private: // Either made explicitly or V3LinkDot made implicitly classp->v3fatalSrc("Can't find class's new"); } + if (classp->isVirtual()) { + nodep->v3error( + "Illegal to call 'new' using an abstract virtual class (IEEE 1800-2017 8.21)"); + } } else { // super.new case // in this case class and taskp() should be properly linked in V3LinkDot.cpp during // "super" reference resolution @@ -3634,10 +3638,6 @@ private: UASSERT_OBJ(nodep->taskp(), nodep, "Unlinked taskp()"); nodep->dtypeFrom(nodep->taskp()); } - if (classp->isVirtual()) { - nodep->v3error( - "Illegal to call 'new' using an abstract virtual class (IEEE 1800-2017 8.21)"); - } userIterate(nodep->taskp(), nullptr); processFTaskRefArgs(nodep); } diff --git a/test_regress/t/t_class_virtual_chain_ctor.pl b/test_regress/t/t_class_virtual_chain_ctor.pl new file mode 100755 index 000000000..5b8136393 --- /dev/null +++ b/test_regress/t/t_class_virtual_chain_ctor.pl @@ -0,0 +1,16 @@ +#!/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(vlt => 1); + +lint(); + +ok(1); +1; diff --git a/test_regress/t/t_class_virtual_chain_ctor.v b/test_regress/t/t_class_virtual_chain_ctor.v new file mode 100644 index 000000000..53a1b4ec8 --- /dev/null +++ b/test_regress/t/t_class_virtual_chain_ctor.v @@ -0,0 +1,34 @@ +// DESCRIPTION: Verilator: Check that an abstract class' contstructor +// can be called indirectly from a constructor of a derived class. +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2023 by Ilya Barkov +// SPDX-License-Identifier: CC0-1.0 + +// It's illegal to call +// VBase b = new; +// see t_class_virtual_bad +virtual class VBase; + function new(); endfunction +endclass + +// Another constructor of an abstact class in the chain +virtual class VChild1 extends VBase; + function new(); + super.new(); + endfunction +endclass + +// It shall be perfectly fine to create an instance of a +// non-abstract VChild2 +class VChild2 extends VChild1; + function new(); + super.new(); + endfunction +endclass + +module t; + initial begin + VChild2 c = new; + end +endmodule