diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 8fdbfc5a8..1adbfd48b 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2770,6 +2770,12 @@ class WidthVisitor final : public VNVisitor { << nodep->prettyNameQ() << " (IEEE 1800-2023 6.20.6)"); } + if (nodep->varp()->isClassMember() && !nodep->varp()->isFuncLocal() + && !nodep->varp()->lifetime().isStatic() && m_ftaskp && m_ftaskp->isStatic()) { + nodep->v3error("Cannot access non-static member variable " + << nodep->prettyNameQ() << " from a static method " + << m_ftaskp->prettyNameQ() << " without object (IEEE 1800-2023 8.10)"); + } nodep->didWidth(true); } @@ -3309,6 +3315,10 @@ class WidthVisitor final : public VNVisitor { void visit(AstThisRef* nodep) override { if (nodep->didWidthAndSet()) return; nodep->dtypep(iterateEditMoveDTypep(nodep, nodep->childDTypep())); + if (m_ftaskp && m_ftaskp->isStatic()) { + nodep->v3error("Cannot use 'this' in a static method " + << m_ftaskp->prettyNameQ() << " (IEEE 1800-2023 8.10-8.11)"); + } } void visit(AstClassRefDType* nodep) override { if (nodep->didWidthAndSet()) return; diff --git a/test_regress/t/t_class_static_member_bad.out b/test_regress/t/t_class_static_member_bad.out new file mode 100644 index 000000000..2733cd82d --- /dev/null +++ b/test_regress/t/t_class_static_member_bad.out @@ -0,0 +1,8 @@ +%Error: t/t_class_static_member_bad.v:10:11: Cannot access non-static member variable 'mb' from a static method 'foo' without object (IEEE 1800-2023 8.10) + 10 | void'(mb.try_put(this)); + | ^~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: t/t_class_static_member_bad.v:10:22: Cannot use 'this' in a static method 'foo' (IEEE 1800-2023 8.10-8.11) + 10 | void'(mb.try_put(this)); + | ^~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_class_static_member_bad.py b/test_regress/t/t_class_static_member_bad.py new file mode 100755 index 000000000..392b50fb6 --- /dev/null +++ b/test_regress/t/t_class_static_member_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2026 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 + +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_static_member_bad.v b/test_regress/t/t_class_static_member_bad.v new file mode 100644 index 000000000..b64dba9db --- /dev/null +++ b/test_regress/t/t_class_static_member_bad.v @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2026 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +class Cls; + mailbox #(Cls) mb = new(); + static task foo(); + void'(mb.try_put(this)); + endtask +endclass