* Fix class extend references between queues (#7195).

Fixes #7195.
This commit is contained in:
Wilson Snyder 2026-03-05 18:03:58 -05:00
parent caf624944f
commit c2d65c2e13
4 changed files with 92 additions and 0 deletions

View File

@ -40,6 +40,7 @@ Verilator 5.047 devel
* Fix eliminating assignments to DPI-read variables (#7158). [Geza Lore, Testorrent USA, Inc.]
* Fix std::randomize() in static function with static class members (#7167) (#7169). [Yilou Wang]
* Fix recursive constant function in $unit scope (#7173) (#7174).
* Fix class extend references between queues (#7195).
* Fix library/hier_block tracing when top name is empty (#7200). [Geza Lore, Testorrent USA, Inc.]

View File

@ -428,6 +428,9 @@ std::string VL_TO_STRING(const VlWide<N_Words>& obj) {
return VL_TO_STRING_W(N_Words, obj.data());
}
template <typename T_Class>
class VlClassRef;
//===================================================================
// Verilog queue and dynamic array container
// There are no multithreaded locks on this; the base variable must
@ -438,6 +441,9 @@ std::string VL_TO_STRING(const VlWide<N_Words>& obj) {
template <typename T_Value, size_t N_MaxSize = 0>
class VlQueue final {
private:
template <typename U_Value, size_t M_MaxSize>
friend class VlQueue;
// TYPES
using Deque = std::deque<T_Value>;
@ -460,6 +466,13 @@ public:
VlQueue(VlQueue&&) = default;
VlQueue& operator=(const VlQueue&) = default;
VlQueue& operator=(VlQueue&&) = default;
// Template constuctors that construct from containers holding sub-classes
template <typename T_Subclass>
inline VlQueue(const VlQueue<VlClassRef<T_Subclass>>&);
template <typename T_Subclass>
inline VlQueue(VlQueue<VlClassRef<T_Subclass>>&&);
bool operator==(const VlQueue& rhs) const { return m_deque == rhs.m_deque; }
bool operator!=(const VlQueue& rhs) const { return m_deque != rhs.m_deque; }
bool operator<(const VlQueue& rhs) const {
@ -2151,4 +2164,17 @@ inline T VL_NULL_CHECK(T t, const char* filename, int linenum) {
//======================================================================
template <typename T_Value, size_t N_MaxSize>
template <typename T_Subclass>
VlQueue<T_Value, N_MaxSize>::VlQueue(const VlQueue<VlClassRef<T_Subclass>>& that)
: m_deque{that.m_deque.begin(), that.m_deque.end()}
, m_defaultValue{that.m_defaultValue} {}
template <typename T_Value, size_t N_MaxSize>
template <typename T_Subclass>
VlQueue<T_Value, N_MaxSize>::VlQueue(VlQueue<VlClassRef<T_Subclass>>&& that)
: m_deque{std::make_move_iterator(that.m_deque.begin()),
std::make_move_iterator(that.m_deque.end())}
, m_defaultValue{std::move(that.m_defaultValue)} {}
#endif // Guard

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# 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-FileCopyrightText: 2026 Wilson Snyder
# 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,47 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Wilson Snyder
// SPDX-License-Identifier: CC0-1.0
// Issue #7195
module t;
class uvm_reg;
endclass
class reg_slave_DATA extends uvm_reg;
endclass
class reg_slave_TABLES extends uvm_reg;
function uvm_reg create(string name = "");
reg_slave_TABLES tmp;
tmp = new;
return tmp;
endfunction
endclass
class reg_block_slave;
reg_slave_DATA DATA;
rand reg_slave_TABLES TABLES[4];
virtual function void build();
foreach (TABLES[i])
TABLES[i] = new;
this.configure(TABLES); // Issue was here
endfunction
function void configure(uvm_reg reg_a[]);
foreach (reg_a[i])
$display("%p", reg_a[i]);
endfunction
endclass
initial begin
reg_block_slave c;
c = new;
c.build;
$finish;
end
endmodule