mirror of
https://github.com/verilator/verilator.git
synced 2025-04-16 01:26:54 +00:00
Fix range access to fields under classes that depend on parameter resolution (#4681)
Signed-off-by: Krzysztof Boronski <kboronski@antmicro.com>
This commit is contained in:
parent
2dba76a7c2
commit
cc982ec7fe
@ -931,7 +931,7 @@ AstNode* AstArraySel::baseFromp(AstNode* nodep, bool overMembers) {
|
||||
nodep = VN_AS(nodep, MemberSel)->fromp();
|
||||
continue;
|
||||
}
|
||||
// AstNodeSelPre stashes the associated variable under an ATTROF
|
||||
// AstNodePreSel stashes the associated variable under an ATTROF
|
||||
// of VAttrType::VAR_BASE so it isn't constified
|
||||
else if (VN_IS(nodep, AttrOf)) {
|
||||
nodep = VN_AS(nodep, AttrOf)->fromp();
|
||||
|
@ -3343,7 +3343,19 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
||||
m_ds.init(m_curSymp);
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
iterateAndNextNull(nodep->thsp());
|
||||
iterateAndNextNull(nodep->attrp());
|
||||
}
|
||||
|
||||
if (nodep->attrp()) {
|
||||
AstNode* const attrp = nodep->attrp()->unlinkFrBack();
|
||||
VL_DO_DANGLING(attrp->deleteTree(), attrp);
|
||||
}
|
||||
AstNode* const basefromp = AstArraySel::baseFromp(nodep, false);
|
||||
if (VN_IS(basefromp, Replicate)) {
|
||||
// From {...}[...] syntax in IEEE 2017
|
||||
if (basefromp) UINFO(1, " Related node: " << basefromp << endl);
|
||||
} else {
|
||||
nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::VAR_BASE,
|
||||
basefromp->cloneTree(false)});
|
||||
}
|
||||
}
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
@ -3742,6 +3754,8 @@ class LinkDotResolveVisitor final : public VNVisitor {
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
void visit(AstAttrOf* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
void visit(AstNode* nodep) override {
|
||||
checkNoDot(nodep);
|
||||
iterateChildren(nodep);
|
||||
|
@ -181,19 +181,6 @@ class LinkResolveVisitor final : public VNVisitor {
|
||||
nodep->scopeNamep(new AstScopeName{nodep->fileline(), false});
|
||||
}
|
||||
}
|
||||
void visit(AstNodePreSel* nodep) override {
|
||||
if (!nodep->attrp()) {
|
||||
iterateChildren(nodep);
|
||||
AstNode* const basefromp = AstArraySel::baseFromp(nodep, false);
|
||||
if (VN_IS(basefromp, Replicate)) {
|
||||
// From {...}[...] syntax in IEEE 2017
|
||||
if (basefromp) UINFO(1, " Related node: " << basefromp << endl);
|
||||
} else {
|
||||
nodep->attrp(new AstAttrOf{nodep->fileline(), VAttrType::VAR_BASE,
|
||||
basefromp->cloneTree(false)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void visit(AstCaseItem* nodep) override {
|
||||
// Move default caseItems to the bottom of the list
|
||||
|
22
test_regress/t/t_selextract_in_paramextends.pl
Executable file
22
test_regress/t/t_selextract_in_paramextends.pl
Executable file
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2023 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
|
||||
|
||||
scenarios(simulator => 1);
|
||||
|
||||
compile(
|
||||
verilator_flags2 => ["--timing"],
|
||||
);
|
||||
|
||||
execute(
|
||||
check_finished => 1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
44
test_regress/t/t_selextract_in_paramextends.v
Normal file
44
test_regress/t/t_selextract_in_paramextends.v
Normal file
@ -0,0 +1,44 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain, for
|
||||
// any use, without warranty, 2023 by Antmicro Ltd.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
typedef class Foo;
|
||||
|
||||
virtual class Bar #(type T);
|
||||
T m_val;
|
||||
endclass
|
||||
|
||||
class Baz;
|
||||
rand bit [3:0] m_sus;
|
||||
endclass
|
||||
|
||||
class Foo extends Bar#(Baz);
|
||||
function new();
|
||||
Baz baz;
|
||||
super.new();
|
||||
baz = new;
|
||||
super.m_val = baz;
|
||||
endfunction
|
||||
|
||||
task update_value(Foo foo, bit [1:0] val);
|
||||
m_val.m_sus[1:0] = val;
|
||||
endtask
|
||||
endclass
|
||||
|
||||
module test();
|
||||
initial begin
|
||||
Foo foo = new;
|
||||
|
||||
for (int i = 0; i < 10; i++) begin
|
||||
logic [3:0] v;
|
||||
foo.update_value(foo, i[1:0]);
|
||||
v = foo.m_val.m_sus;
|
||||
if (v[1:0] != i[1:0]) $stop;
|
||||
end
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user