From 30f3774134778d25321c415785c10fd7e1b6f83c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 7 Sep 2020 17:26:53 -0400 Subject: [PATCH] Support const object new() assignments. --- Changes | 2 ++ src/V3Width.cpp | 15 ++++++++++----- test_regress/t/t_class_local.v | 4 ++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/Changes b/Changes index d120e7359..097a341f8 100644 --- a/Changes +++ b/Changes @@ -5,6 +5,8 @@ The contributors that suggested a given feature are shown in []. Thanks! * Verilator 4.101 devel +**** Support const object new() assignments. + * Verilator 4.100 2020-09-07 diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 2e0245d12..e10e536b1 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -128,6 +128,11 @@ public: return m_dtypep; } AstNodeDType* dtypeNullp() const { return m_dtypep; } + AstNodeDType* dtypeNullSkipRefp() const { + AstNodeDType* dtp = dtypeNullp(); + if (dtp) dtp = dtp->skipRefp(); + return dtp; + } AstNodeDType* dtypeOverridep(AstNodeDType* defaultp) const { if (m_stage == PRELIM) v3fatalSrc("Parent dtype should be a final-stage action"); return m_dtypep ? m_dtypep : defaultp; @@ -478,7 +483,7 @@ private: // signed: Unsigned (11.8.1) // width: LHS + RHS if (m_vup->prelim()) { - AstNodeDType* vdtypep = m_vup->dtypeNullp(); + AstNodeDType* vdtypep = m_vup->dtypeNullSkipRefp(); if (vdtypep && (VN_IS(vdtypep, AssocArrayDType) // || VN_IS(vdtypep, DynArrayDType) // @@ -602,7 +607,7 @@ private: // LHS, RHS is self-determined // width: value(LHS) * width(RHS) if (m_vup->prelim()) { - AstNodeDType* vdtypep = m_vup->dtypeNullp(); + AstNodeDType* vdtypep = m_vup->dtypeNullSkipRefp(); if (vdtypep && (VN_IS(vdtypep, AssocArrayDType) || VN_IS(vdtypep, DynArrayDType) || VN_IS(vdtypep, QueueDType) || VN_IS(vdtypep, UnpackArrayDType))) { @@ -2725,7 +2730,7 @@ private: virtual void visit(AstNew* nodep) override { if (nodep->didWidthAndSet()) return; - AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullp(), ClassRefDType); + AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullSkipRefp(), ClassRefDType); if (!refp) { // e.g. int a = new; nodep->v3error("new() not expected in this context"); return; @@ -2751,7 +2756,7 @@ private: } virtual void visit(AstNewCopy* nodep) override { if (nodep->didWidthAndSet()) return; - AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullp(), ClassRefDType); + AstClassRefDType* refp = VN_CAST(m_vup->dtypeNullSkipRefp(), ClassRefDType); if (!refp) { // e.g. int a = new; nodep->v3error("new() not expected in this context"); return; @@ -2766,7 +2771,7 @@ private: } virtual void visit(AstNewDynamic* nodep) override { if (nodep->didWidthAndSet()) return; - AstDynArrayDType* adtypep = VN_CAST(m_vup->dtypeNullp(), DynArrayDType); + AstDynArrayDType* adtypep = VN_CAST(m_vup->dtypeNullSkipRefp(), DynArrayDType); if (!adtypep) { // e.g. int a = new; nodep->v3error( "dynamic new() not expected in this context (data type must be dynamic array)"); diff --git a/test_regress/t/t_class_local.v b/test_regress/t/t_class_local.v index 0df89e7a7..fb7ff5ae9 100644 --- a/test_regress/t/t_class_local.v +++ b/test_regress/t/t_class_local.v @@ -13,6 +13,8 @@ class Cls; protected int m_prot = B; endclass + const Cls mod_c = new; + initial begin Cls c; if (c.A != 10) $stop; @@ -21,6 +23,8 @@ endclass c.m_loc = 10; if (c.m_loc != 10) $stop; if (c.m_prot != 20) $stop; + // + if (mod_c.A != 10) $stop; $write("*-* All Finished *-*\n"); $finish; end