Fix segfault when only enum value referenced in package (#5714).

This commit is contained in:
Wilson Snyder 2025-01-04 10:36:34 -05:00
parent 1d0563212e
commit b531001f55
6 changed files with 64 additions and 6 deletions

View File

@ -17,6 +17,7 @@ Verilator 5.033 devel
* Fix man pages what-is section (#5710). [Ahmed El-Mahmoudy]
* Fix pattern assignment to real inside struct (#5713).
* Fix %p format output for real inside struct (#5713).
* Fix segfault when only enum value referenced in package (#5714). [Dan Katz]
Verilator 5.032 2025-01-01

View File

@ -62,7 +62,8 @@ class DeadVisitor final : public VNVisitor {
const bool m_elimCells; // Allow removal of Cells
// List of all encountered to avoid another loop through tree
std::vector<AstVar*> m_varsp;
std::vector<AstNode*> m_dtypesp;
std::vector<AstNode*> m_dtypeElimsp; // Data types might eliminate
std::map<AstNodeDType*, AstNodeModule*> m_dtypePkgsp; // Data type's containing package
std::vector<AstVarScope*> m_vscsp;
std::vector<AstScope*> m_scopesp;
std::vector<AstCell*> m_cellsp;
@ -73,6 +74,7 @@ class DeadVisitor final : public VNVisitor {
// STATE - for current visit position (use VL_RESTORER)
bool m_inAssign = false; // Currently in an assign
AstNodeDType* m_curDTypep = nullptr; // Current NodeDType
AstNodeModule* m_modp = nullptr; // Current module
AstSelLoopVars* m_selloopvarsp = nullptr; // Current loop vars
@ -84,8 +86,11 @@ class DeadVisitor final : public VNVisitor {
}
void checkAll(AstNode* nodep) {
if (nodep != nodep->dtypep()) { // NodeDTypes reference themselves
if (AstNode* const subnodep = nodep->dtypep()) subnodep->user1Inc();
if (AstNode* const subnodep = nodep->dtypep()) {
if (nodep != subnodep // Not NodeDTypes reference themselves
&& m_curDTypep != subnodep) { // Not EnumItem referencing parent Enum
subnodep->user1Inc();
}
}
if (AstNode* const subnodep = nodep->getChildDTypep()) subnodep->user1Inc();
}
@ -98,8 +103,9 @@ class DeadVisitor final : public VNVisitor {
&& !VN_IS(nodep, MemberDType) // Keep member names iff upper type exists
&& !nodep->undead() // VoidDType or something Netlist points to
) {
m_dtypesp.push_back(nodep);
m_dtypeElimsp.push_back(nodep);
}
if (VN_IS(m_modp, Package) || VN_IS(m_modp, Class)) m_dtypePkgsp.emplace(nodep, m_modp);
if (AstNode* const subnodep = nodep->virtRefDTypep()) subnodep->user1Inc();
if (AstNode* const subnodep = nodep->virtRefDType2p()) subnodep->user1Inc();
}
@ -212,6 +218,8 @@ class DeadVisitor final : public VNVisitor {
if (nodep->ifaceViaCellp()) nodep->ifaceViaCellp()->user1Inc();
}
void visit(AstNodeDType* nodep) override {
VL_RESTORER(m_curDTypep);
m_curDTypep = nodep;
iterateChildren(nodep);
checkDType(nodep);
checkAll(nodep);
@ -442,7 +450,8 @@ class DeadVisitor final : public VNVisitor {
}
}
}
for (std::vector<AstNode*>::iterator it = m_dtypesp.begin(); it != m_dtypesp.end(); ++it) {
for (std::vector<AstNode*>::iterator it = m_dtypeElimsp.begin(); it != m_dtypeElimsp.end();
++it) {
if ((*it)->user1() == 0) {
// It's possible that there if a reference to each individual member, but
// not to the dtype itself. Check and don't remove the parent dtype if
@ -517,6 +526,11 @@ public:
vscp->varp()->user1Inc();
}
// If data type has a reference in another package, then keep defining package around
for (auto& itr : m_dtypePkgsp) {
if (itr.first->user1()) itr.second->user1Inc();
}
deadCheckTypedefs();
deadCheckVar();
// We only eliminate scopes when in a flattened structure

View File

@ -341,6 +341,9 @@ module Vt_debug_emitv_sub;
endfunction
real signed r;
endmodule
package Vt_debug_emitv_p;
logic pkgvar;
endpackage
package Vt_debug_emitv_Pkg;
logic signed [31:0] PKG_PARAM;
endpackage

View File

@ -5,7 +5,7 @@
// SPDX-License-Identifier: CC0-1.0
package defs;
int sig;
localparam PAR = 1;
endpackage
import defs::*;

View File

@ -0,0 +1,18 @@
#!/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('simulator')
test.compile()
test.execute()
test.passes()

View File

@ -0,0 +1,22 @@
// 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
package pkg;
typedef enum logic [2:0] {
TWO = 2,
THREE = 3
} enum_t;
endpackage
module t;
localparam L_TWO = pkg::TWO;
initial begin
if (L_TWO != 2) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule