diff --git a/Changes b/Changes index 715c7827b..75c95ee2f 100644 --- a/Changes +++ b/Changes @@ -40,6 +40,7 @@ Verilator 5.009 devel * Fix characters from DEFENV literals for conda (#4035) (#4044). [Tim Snyder] * Fix interface generate begin (#4065). [Srinivasan Venkataramanan] * Fix false error on new const assignment (#4098). [Tudor Timi] +* Fix unpacked structs under classes (#4102). [Tudor Timi] * Fix false ENUMVALUE on expressions and arrays. * Fix unnecessary verilated_std.sv waivers in --waiver-output. diff --git a/src/V3Class.cpp b/src/V3Class.cpp index 61513782a..3c726a3a6 100644 --- a/src/V3Class.cpp +++ b/src/V3Class.cpp @@ -178,7 +178,7 @@ private: void setStructModulep(AstNodeUOrStructDType* const dtypep) { // Give it a pointer to its package and a final name - dtypep->classOrPackagep(m_modp); + dtypep->classOrPackagep(m_classPackagep ? m_classPackagep : m_modp); dtypep->name(dtypep->name() + (VN_IS(dtypep, UnionDType) ? "__union" : "__struct") + cvtToStr(dtypep->uniqueNum())); @@ -193,6 +193,7 @@ private: void visit(AstTypedef* nodep) override { if (nodep->user1SetOnce()) return; iterateChildren(nodep); + if (m_classPackagep) m_classPackagep->addStmtsp(nodep->unlinkFrBack()); AstNodeUOrStructDType* const dtypep = VN_CAST(nodep->dtypep(), NodeUOrStructDType); if (dtypep && !dtypep->packed()) { diff --git a/src/V3EmitCImp.cpp b/src/V3EmitCImp.cpp index ead32fb03..ee9a96306 100644 --- a/src/V3EmitCImp.cpp +++ b/src/V3EmitCImp.cpp @@ -514,7 +514,7 @@ class EmitCImp final : EmitCFunc { // Compute the hash of the dependencies, so we can add it to the filenames to // disambiguate them V3Hash hash; - for (const string& name : *m_requiredHeadersp) { hash += name; } + for (const string& name : *m_requiredHeadersp) hash += name; m_subFileName = "DepSet_" + hash.toString(); // Open output file openNextOutputFile(*m_requiredHeadersp, m_subFileName); diff --git a/src/V3File.cpp b/src/V3File.cpp index 506f67a64..89d82c17f 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -937,7 +937,7 @@ V3OutFile::~V3OutFile() { void V3OutFile::putsForceIncs() { const V3StringList& forceIncs = v3Global.opt.forceIncs(); - for (const string& i : forceIncs) { puts("#include \"" + i + "\"\n"); } + for (const string& i : forceIncs) puts("#include \"" + i + "\"\n"); } void V3OutCFile::putsGuard() { diff --git a/test_regress/t/t_struct_unpacked.v b/test_regress/t/t_struct_unpacked.v index 14190f693..ef0ad6b2a 100644 --- a/test_regress/t/t_struct_unpacked.v +++ b/test_regress/t/t_struct_unpacked.v @@ -7,6 +7,19 @@ `define stop $stop `define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +class Cls; + typedef struct { + string m_strg; + } underclass_t; + + underclass_t m_cstr; + function underclass_t get_cstr(); + m_cstr.m_strg = "foo"; + return m_cstr; + endfunction +endclass + + module x; typedef struct { int a, b; @@ -27,6 +40,7 @@ module x; embedded_t t [1:0]; istr_t istr; string s; + Cls c; initial begin t[1].a = 2; @@ -43,6 +57,10 @@ module x; s = $sformatf("%p", istr); `checks(s, "'{m_i:'hffff, m_s:\"str2\"}"); + c = new; + s = c.get_cstr().m_strg; + `checks(s, "foo"); + $write("*-* All Finished *-*\n"); $finish; end