Fix class/var named identically to an enclosing-scope type (#7827) (#7828)

Fixes #7827.
This commit is contained in:
Tom Jackson 2026-06-24 00:43:31 +00:00 committed by GitHub
parent 0cd13f80c9
commit 2baca68f86
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 80 additions and 2 deletions

View File

@ -279,6 +279,7 @@ Tobias Jensen
Tobias Rosenkranz
Tobias Wölfel
Todd Strader
Tom Jackson
Tom Manner
Tomasz Gorochowik
Topa Topino

View File

@ -3562,12 +3562,18 @@ class LinkDotResolveVisitor final : public VNVisitor {
}
static VSymEnt* findIdFallbackSkipMemberDType(VSymEnt* lookp, const string& name) {
VSymEnt* shadowEntp = nullptr; // Shadowing variable: not a type, kept for error report
while (lookp) {
VSymEnt* const foundp = lookp->findIdFlat(name);
if (foundp && !VN_IS(foundp->nodep(), MemberDType)) return foundp;
if (foundp && !VN_IS(foundp->nodep(), MemberDType)) {
// A variable is not a type candidate (IEEE 1800-2023 6.18); skip it so an
// enclosing type is found, but keep it to preserve the "found: VAR" error.
if (!VN_IS(foundp->nodep(), Var)) return foundp;
if (!shadowEntp) shadowEntp = foundp;
}
lookp = lookp->fallbackp();
}
return nullptr;
return shadowEntp;
}
void symIterateChildren(AstNode* nodep, VSymEnt* symp) {

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,53 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// A data member/variable named identically to a type from an enclosing scope
// must resolve its type specifier against the enclosing-scope type, not against
// the just-declared variable (IEEE 1800-2023 6.18). This is the UVM RAL /
// peakrdl-regblock pattern: 'rand <block_t> <same_name>;'.
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 Tom Jackson
// SPDX-License-Identifier: CC0-1.0
// verilog_format: off
`define stop $stop
`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0);
// verilog_format: on
typedef logic [7:0] my_t; // type at $unit scope
class C;
my_t my_t; // member named the same as its (outer-scope) type
endclass
class D;
my_t a; // second use of the type name after the shadowing variable...
my_t my_t; // ... is also legal; both resolve to the $unit typedef
endclass
// The exact RAL shape: class member named after its class type
class my_blk;
int x;
endclass
class parent;
rand my_blk my_blk;
endclass
module t;
my_t my_t; // also legal at module scope
initial begin
static C c = new;
static parent p = new;
c.my_t = 8'hAB;
p.my_blk = new;
p.my_blk.x = 5;
my_t = 8'h12;
`checkh(c.my_t, 8'hAB);
`checkh(p.my_blk.x, 5);
`checkh(my_t, 8'h12);
$write("*-* All Finished *-*\n");
$finish;
end
endmodule