From 35374f09b4ac09e74ab1d1eaaa6cbb70f2a99b4c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 24 Nov 2020 18:15:49 -0500 Subject: [PATCH] Add error on class extending itself --- src/V3LinkDot.cpp | 23 +++++++++++++--------- test_regress/t/t_class_extends_rec_bad.out | 4 ++++ test_regress/t/t_class_extends_rec_bad.pl | 19 ++++++++++++++++++ test_regress/t/t_class_extends_rec_bad.v | 13 ++++++++++++ 4 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 test_regress/t/t_class_extends_rec_bad.out create mode 100755 test_regress/t/t_class_extends_rec_bad.pl create mode 100644 test_regress/t/t_class_extends_rec_bad.v diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index e93d0815a..9eede8663 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2774,15 +2774,20 @@ private: if (AstClass* classp = VN_CAST(foundp->nodep(), Class)) { UINFO(8, "Import to " << nodep << " from export class " << classp << endl); - AstClassRefDType* newp - = new AstClassRefDType{nodep->fileline(), classp}; - cextp->childDTypep(newp); - classp->isExtended(true); - nodep->isExtended(true); - VSymEnt* srcp = m_statep->getNodeSym(classp); - m_curSymp->importFromClass(m_statep->symsp(), srcp); - VL_DO_DANGLING(cpackagerefp->unlinkFrBack()->deleteTree(), - cpackagerefp); + if (classp == nodep) { + cextp->v3error("Attempting to extend class " + << nodep->prettyNameQ() << " from itself"); + } else { + AstClassRefDType* newp + = new AstClassRefDType{nodep->fileline(), classp}; + cextp->childDTypep(newp); + classp->isExtended(true); + nodep->isExtended(true); + VSymEnt* srcp = m_statep->getNodeSym(classp); + m_curSymp->importFromClass(m_statep->symsp(), srcp); + VL_DO_DANGLING(cpackagerefp->unlinkFrBack()->deleteTree(), + cpackagerefp); + } ok = true; } } diff --git a/test_regress/t/t_class_extends_rec_bad.out b/test_regress/t/t_class_extends_rec_bad.out new file mode 100644 index 000000000..c5ffe68ce --- /dev/null +++ b/test_regress/t/t_class_extends_rec_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_class_extends_rec_bad.v:7:31: Attempting to extend class 'RecursiveExtCls' from itself + 7 | class RecursiveExtCls extends RecursiveExtCls; + | ^~~~~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_class_extends_rec_bad.pl b/test_regress/t/t_class_extends_rec_bad.pl new file mode 100755 index 000000000..7be596e0f --- /dev/null +++ b/test_regress/t/t_class_extends_rec_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 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(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_class_extends_rec_bad.v b/test_regress/t/t_class_extends_rec_bad.v new file mode 100644 index 000000000..2470977f8 --- /dev/null +++ b/test_regress/t/t_class_extends_rec_bad.v @@ -0,0 +1,13 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class RecursiveExtCls extends RecursiveExtCls; + int i; +endclass + +module t (/*AUTOARG*/); + RecursiveExtCls cls = new; +endmodule