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:
parent
446bec3d1a
commit
ff056ffb0d
|
|
@ -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},
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue