diff --git a/src/V3Width.cpp b/src/V3Width.cpp index b5c35e89b..506769313 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -3106,7 +3106,14 @@ class WidthVisitor final : public VNVisitor { UINFO(4, "dtWidthed " << nodep); } void visit(AstNodeUOrStructDType* nodep) override { + if (nodep->doingWidth()) { // Early exit if have circular parameter definition + nodep->v3error("Struct's type is circular: " << nodep->prettyName()); + nodep->dtypeSetBit(); + nodep->doingWidth(false); + return; + } if (nodep->didWidthAndSet()) return; // This node is a dtype & not both PRELIMed+FINALed + nodep->doingWidth(true); UINFO(5, " NODEUORS " << nodep); // UINFOTREE(9, nodep, "", "class-in"); if (!nodep->packed() && v3Global.opt.structsPacked()) nodep->packed(true); @@ -3167,6 +3174,7 @@ class WidthVisitor final : public VNVisitor { } else { nodep->widthForce(1, 1); } + nodep->doingWidth(false); // UINFOTREE(9, nodep, "", "class-out"); } void visit(AstClass* nodep) override { diff --git a/test_regress/t/t_struct_circ_bad.out b/test_regress/t/t_struct_circ_bad.out new file mode 100644 index 000000000..ef901455e --- /dev/null +++ b/test_regress/t/t_struct_circ_bad.out @@ -0,0 +1,6 @@ +%Error: t/t_struct_circ_bad.v:11:11: Struct's type is circular: t.t2_t + : ... note: In instance 't' + 11 | typedef struct packed { + | ^~~~~~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: Exiting due to diff --git a/test_regress/t/t_struct_circ_bad.py b/test_regress/t/t_struct_circ_bad.py new file mode 100755 index 000000000..55203b6c9 --- /dev/null +++ b/test_regress/t/t_struct_circ_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 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_struct_circ_bad.v b/test_regress/t/t_struct_circ_bad.v new file mode 100644 index 000000000..389374277 --- /dev/null +++ b/test_regress/t/t_struct_circ_bad.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + typedef t1_t; + + typedef struct packed { + t1_t x; // <--- Bad: Circular + } t2_t; + + typedef t2_t [1:0] t3_t; + + typedef t3_t t1_t; // <--- Bad: Circular (or above) + + t1_t x; + +endmodule