diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 861714e34..6f541236b 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -4782,6 +4782,15 @@ class WidthVisitor final : public VNVisitor { } void methodCallIfaceRef(AstMethodCall* nodep, AstIfaceRefDType* adtypep) { AstIface* const ifacep = adtypep->ifacep(); + if (!ifacep) { + // A sub-interface reached through a virtual interface handle has a + // ref dtype with cellp set but ifacep null; the per-instance binding + // is not modelled, so the call cannot be resolved to one instance. + nodep->v3warn(E_UNSUPPORTED, "Unsupported: method call on a sub-interface " + "accessed through a virtual interface"); + nodep->dtypeSetVoid(); + return; + } UINFO(5, __FUNCTION__ << ":" << nodep); if (AstNodeFTask* const ftaskp = VN_CAST(m_memberMap.findMember(ifacep, nodep->name()), NodeFTask)) { diff --git a/test_regress/t/t_interface_virtual_sub_iface_method_bad.out b/test_regress/t/t_interface_virtual_sub_iface_method_bad.out new file mode 100644 index 000000000..5a9ec7a0b --- /dev/null +++ b/test_regress/t/t_interface_virtual_sub_iface_method_bad.out @@ -0,0 +1,6 @@ +%Error-UNSUPPORTED: t/t_interface_virtual_sub_iface_method_bad.v:21:16: Unsupported: method call on a sub-interface accessed through a virtual interface + : ... note: In instance 't' + 21 | vif.sub_if.set_active(); + | ^~~~~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_interface_virtual_sub_iface_method_bad.py b/test_regress/t/t_interface_virtual_sub_iface_method_bad.py new file mode 100755 index 000000000..38cf36b43 --- /dev/null +++ b/test_regress/t/t_interface_virtual_sub_iface_method_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_interface_virtual_sub_iface_method_bad.v b/test_regress/t/t_interface_virtual_sub_iface_method_bad.v new file mode 100644 index 000000000..723751c03 --- /dev/null +++ b/test_regress/t/t_interface_virtual_sub_iface_method_bad.v @@ -0,0 +1,33 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain. +// SPDX-FileCopyrightText: 2026 PlanV GmbH +// SPDX-License-Identifier: CC0-1.0 + +interface inner_if; + logic active = 1'b0; + function automatic void set_active(); + active = 1'b1; + endfunction +endinterface + +interface outer_if; + inner_if sub_if (); +endinterface + +class cfg_c; + virtual outer_if vif; + function void doit(); + vif.sub_if.set_active(); + endfunction +endclass + +module t; + outer_if oif (); + cfg_c cfg; + initial begin + cfg = new(); + cfg.vif = oif; + cfg.doit(); + end +endmodule