Fix inside operator crash with impure expression and unsized range literals

When the inside operator is used with an impure LHS expression (e.g.
associative array element access) and unsized integer range literals,
the temp variable created to purify the expression inherits an unsized
dtype, triggering "How can LHS be unsized?" assertion in visit(AstNodeAssign).
Ensure the temp variable dtype is sized before creation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Yilou Wang 2026-02-12 18:15:47 +01:00
parent 446bec3d1a
commit ff056ffb0d
3 changed files with 65 additions and 1 deletions

View File

@ -3159,8 +3159,17 @@ class WidthVisitor final : public VNVisitor {
// executed so, there is no need for purification since they cannot generate sideeffects.
if (!m_constraintp && !nodep->exprp()->isPure()) {
FileLine* const fl = nodep->exprp()->fileline();
// Ensure sized dtype for temp variable
AstNodeDType* const exprDtp = nodep->exprp()->dtypep();
const int w = exprDtp->width();
AstNodeDType* const tempDTypep
= exprDtp->widthSized()
? exprDtp
: exprDtp->isFourstate()
? nodep->findLogicDType(w, w, exprDtp->numeric())
: nodep->findBitDType(w, w, exprDtp->numeric());
AstVar* const varp = new AstVar{fl, VVarType::XTEMP, m_insideTempNames.get(nodep),
nodep->exprp()->dtypep()};
tempDTypep};
exprp = new AstVarRef{fl, varp, VAccess::READ};
exprStmtp = new AstExprStmt{fl,
new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE},

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,37 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain.
// SPDX-FileCopyrightText: 2026 PlanV GmbH
// SPDX-License-Identifier: CC0-1.0
module t;
bit [7:0] str_arr[string];
string str_key;
bit [7:0] int_arr[int];
int int_key;
int counter = 0;
function bit [7:0] get_val();
counter++;
return 25;
endfunction
initial begin
str_arr["test"] = 25;
str_key = "test";
if (!(str_arr[str_key] inside {[10:50]})) $stop;
if (str_arr[str_key] inside {[100:200]}) $stop;
int_arr[0] = 25;
int_key = 0;
if (!(int_arr[int_key] inside {[10:50]})) $stop;
if (int_arr[int_key] inside {[100:200]}) $stop;
if (!(get_val() inside {[10:50]})) $stop;
if (get_val() inside {[100:200]}) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule