Support empty queue literals as function and task arguments (#8501) (#8502)

This commit is contained in:
Francesco Urbani
2026-09-26 08:11:49 -04:00
committed by GitHub
parent d1eb78f4e8
commit eec929e40e
5 changed files with 46 additions and 12 deletions
+1
View File
@@ -98,6 +98,7 @@ Fan Shupei
february cozzocrea
Felix Neumärker
Felix Yan
Francesco Urbani
Frans Skarman
Fuad Ismail
Furqan Nadir
+22 -8
View File
@@ -1608,7 +1608,8 @@ class WidthVisitor final : public VNVisitor {
}
void visit(AstEmptyQueue* nodep) override {
nodep->dtypeSetEmptyQueue();
if (!VN_IS(nodep->backp(), Assign) && !VN_IS(nodep->backp(), Var)) {
if (!VN_IS(nodep->backp(), Assign) && !VN_IS(nodep->backp(), Var)
&& !VN_IS(nodep->backp(), Arg)) {
nodep->v3warn(E_UNSUPPORTED,
"Unsupported/Illegal: empty queue ('{}') in this context");
}
@@ -6240,14 +6241,15 @@ class WidthVisitor final : public VNVisitor {
nodep->replaceWith(newp);
// UINFOTREE(9, newp, "", "apat-out");
}
AstNodeExpr* newConsDynArrayOrQueue(FileLine* fileline, const AstNodeDType* dtypep) {
if (VN_IS(dtypep, DynArrayDType)) return new AstConsDynArray{fileline};
if (VN_IS(dtypep, QueueDType)) return new AstConsQueue{fileline};
return nullptr;
}
void patternDynArrayOrQueue(AstPattern* nodep, AstNodeDType* arrayp) {
AstNodeExpr* newp = nullptr;
AstNodeExpr* newp = newConsDynArrayOrQueue(nodep->fileline(), arrayp);
UASSERT_OBJ(newp, nodep, "Expected dynamic array or queue data type");
const bool isDynArray = VN_IS(arrayp, DynArrayDType);
if (isDynArray) {
newp = new AstConsDynArray{nodep->fileline()};
} else {
newp = new AstConsQueue{nodep->fileline()};
}
newp->dtypeFrom(arrayp);
for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp;
patp = VN_AS(patp->nextp(), PatMember)) {
@@ -7878,9 +7880,21 @@ class WidthVisitor final : public VNVisitor {
for (const auto& tconnect : tconnects) {
const AstVar* const portp = tconnect.first;
const AstArg* const argp = tconnect.second;
AstNodeExpr* const pinp = argp->exprp();
AstNodeExpr* pinp = argp->exprp();
if (!pinp) continue; // Argument error we'll find later
AstNodeDType* const portDTypep = portp->dtypep()->skipRefToEnump();
if (VN_IS(pinp, EmptyQueue)) {
AstNodeExpr* newp = newConsDynArrayOrQueue(pinp->fileline(), portDTypep);
if (!newp) {
pinp->v3warn(E_UNSUPPORTED,
"Unsupported/Illegal: empty queue ('{}') in this context");
newp = new AstConst{pinp->fileline(), AstConst::Unsized32{}, 0};
}
newp->dtypeFrom(portDTypep);
pinp->replaceWith(newp);
VL_DO_DANGLING(pushDeletep(pinp), pinp);
pinp = newp;
}
const AstNodeDType* const pinDTypep = pinp->dtypep()->skipRefToEnump();
const AstIfaceRefDType* const portIfacep
= VN_CAST(portDTypep->elemDTypep(true), IfaceRefDType);
+8 -4
View File
@@ -1,10 +1,14 @@
%Error-UNSUPPORTED: t/t_queue_empty_bad.v:11:9: Unsupported/Illegal: empty queue ('{}') in this context
%Error-UNSUPPORTED: t/t_queue_empty_bad.v:14:9: Unsupported/Illegal: empty queue ('{}') in this context
: ... note: In instance 't'
11 | i = {} + 1;
14 | i = {} + 1;
| ^
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error-UNSUPPORTED: t/t_queue_empty_bad.v:13:7: Unsupported/Illegal: empty queue ('{}') in this assign context
%Error-UNSUPPORTED: t/t_queue_empty_bad.v:16:7: Unsupported/Illegal: empty queue ('{}') in this assign context
: ... note: In instance 't'
13 | i = {};
16 | i = {};
| ^
%Error-UNSUPPORTED: t/t_queue_empty_bad.v:18:16: Unsupported/Illegal: empty queue ('{}') in this context
: ... note: In instance 't'
18 | scalar_arg({});
| ^
%Error: Exiting due to
+5
View File
@@ -5,6 +5,9 @@
// SPDX-License-Identifier: CC0-1.0
module t;
task scalar_arg(int value);
endtask
initial begin
int i;
@@ -12,6 +15,8 @@ module t;
i = {};
scalar_arg({});
$write("*-* All Finished *-*\n");
$finish;
end
+10
View File
@@ -9,8 +9,18 @@ module t;
if (q.size != 0) $stop;
endtask
task qtsk(int q[$]);
if (q.size != 0) $stop;
endtask
task dtsk(int q[]);
if (q.size != 0) $stop;
endtask
initial begin
tsk();
qtsk({});
dtsk({});
$write("*-* All Finished *-*\n");
$finish;