Fix typedef of parameterized class for member access (#5977)
Defer RefDType resolution in linkDotPrimary when the classOrPackageRef target is a typedef to a parameterized class. Previously only direct class references were deferred, so `typedef outer_cls#(params) drv_t; drv_t::beat_t x;` would resolve against the generic class which V3Param later deletes.
This commit is contained in:
parent
388fb9db2d
commit
c2d3655569
|
|
@ -5310,6 +5310,11 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
|||
iterate(cpackagep);
|
||||
return;
|
||||
}
|
||||
// Also defer if target is a typedef to a parameterized class (#5977)
|
||||
if (m_statep->forPrimary() && isParamedClassRef(cpackagerefp)) {
|
||||
iterate(cpackagep);
|
||||
return;
|
||||
}
|
||||
if (!cpackagerefp->classOrPackageSkipp()) {
|
||||
VSymEnt* const foundp = m_statep->resolveClassOrPackage(
|
||||
m_ds.m_dotSymp, cpackagerefp, true, false, "class/package reference");
|
||||
|
|
|
|||
|
|
@ -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(verilator_flags2=["--binary"])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain.
|
||||
// SPDX-FileCopyrightText: 2026 Leela Pakanati
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Test for issue #5977: Typedef of parameterized class for member access
|
||||
|
||||
// verilog_format: off
|
||||
`define stop $stop
|
||||
`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0);
|
||||
// verilog_format: on
|
||||
|
||||
package pkg;
|
||||
class cls_l0 #(parameter AW = 32);
|
||||
logic [AW-1:0] addr;
|
||||
function new();
|
||||
addr = '0;
|
||||
endfunction
|
||||
endclass
|
||||
|
||||
class cls_l1 #(parameter int AW = 32);
|
||||
typedef cls_l0 #(.AW(AW)) beat_t;
|
||||
endclass
|
||||
endpackage
|
||||
|
||||
module t;
|
||||
// Typedef of parameterized class, then access member typedef via ::
|
||||
typedef pkg::cls_l1 #(.AW(64)) drv64_t;
|
||||
typedef pkg::cls_l1 #(.AW(128)) drv128_t;
|
||||
|
||||
initial begin
|
||||
// Access class-type typedef member through module-level typedef
|
||||
automatic drv64_t::beat_t item1 = new;
|
||||
automatic drv128_t::beat_t item2 = new;
|
||||
item1.addr = 64'hDEAD_BEEF_CAFE_BABE;
|
||||
|
||||
`checkd(item1.addr, 64'hDEAD_BEEF_CAFE_BABE);
|
||||
`checkd($bits(item1.addr), 64);
|
||||
`checkd($bits(item2.addr), 128);
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#!/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.top_filename = "t/t_class_param_typedef8.v"
|
||||
|
||||
test.compile(verilator_flags2=['--binary', '-fno-inline'])
|
||||
|
||||
test.execute()
|
||||
|
||||
test.passes()
|
||||
Loading…
Reference in New Issue