From f5ae58ddab32c023ecb1a27340f37c496325df7f Mon Sep 17 00:00:00 2001 From: Pawel Klopotek Date: Wed, 19 Aug 2026 08:04:28 +0200 Subject: [PATCH] Fix unpacked array passing to logic task arg error (#8148) Signed-off-by: Pawel Klopotek --- src/V3Width.cpp | 8 ++-- .../t/t_invalid_task_arguments_bad.out | 40 +++++++++++++++---- test_regress/t/t_invalid_task_arguments_bad.v | 25 ++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/V3Width.cpp b/src/V3Width.cpp index fd35b2ed6..f87dc9ddb 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -7545,9 +7545,11 @@ class WidthVisitor final : public VNVisitor { relinkHandle.relink(newp); } if (portp->isWritable()) V3LinkLValue::linkLValueSet(pinp); - if (VN_IS(pinDTypep, BasicDType) && portp->direction() != VDirection::REF - && (VN_IS(portDTypep, UnpackArrayDType) || VN_IS(portDTypep, DynArrayDType) - || VN_IS(portDTypep, QueueDType) || VN_IS(portDTypep, AssocArrayDType))) { + if (portp->direction() != VDirection::REF + && !(portp->basicp() + && portp->basicp()->untyped()) // for properties, handled in V3AssertPre + && ((VN_IS(portDTypep, BasicDType) && pinDTypep->isNonPackedArray()) + || (VN_IS(pinDTypep, BasicDType) && portDTypep->isNonPackedArray()))) { pinp->v3error("Function Argument expects " << portDTypep->prettyDTypeNameQ() << ", got " << pinDTypep->prettyDTypeNameQ()); diff --git a/test_regress/t/t_invalid_task_arguments_bad.out b/test_regress/t/t_invalid_task_arguments_bad.out index a81ca08f8..699f0d8e0 100644 --- a/test_regress/t/t_invalid_task_arguments_bad.out +++ b/test_regress/t/t_invalid_task_arguments_bad.out @@ -1,18 +1,42 @@ -%Error: t/t_invalid_task_arguments_bad.v:25:20: Function Argument expects 'logic[30:0]$[]', got 'IData' +%Error: t/t_invalid_task_arguments_bad.v:44:20: Function Argument expects 'logic[30:0]$[]', got 'IData' : ... note: In instance 't' - 25 | dyn_task(.data($urandom)); + 44 | dyn_task(.data($urandom)); | ^~~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_invalid_task_arguments_bad.v:26:25: Function Argument expects 'logic[30:0]$[3:0]', got 'IData' +%Error: t/t_invalid_task_arguments_bad.v:45:25: Function Argument expects 'logic[30:0]$[3:0]', got 'IData' : ... note: In instance 't' - 26 | unpacked_task(.data($urandom)); + 45 | unpacked_task(.data($urandom)); | ^~~~~~~~ -%Error: t/t_invalid_task_arguments_bad.v:27:22: Function Argument expects 'logic[30:0]$[$]', got 'IData' +%Error: t/t_invalid_task_arguments_bad.v:46:22: Function Argument expects 'logic[30:0]$[$]', got 'IData' : ... note: In instance 't' - 27 | queue_task(.data($urandom)); + 46 | queue_task(.data($urandom)); | ^~~~~~~~ -%Error: t/t_invalid_task_arguments_bad.v:28:22: Function Argument expects 'logic[30:0]$[int]', got 'IData' +%Error: t/t_invalid_task_arguments_bad.v:47:22: Function Argument expects 'logic[30:0]$[int]', got 'IData' : ... note: In instance 't' - 28 | assoc_task(.data($urandom)); + 47 | assoc_task(.data($urandom)); | ^~~~~~~~ +%Error: t/t_invalid_task_arguments_bad.v:48:23: Function Argument expects 'logic', got 'logic$[3:0]' + : ... note: In instance 't' + 48 | scalar_task(.data(unpacked_data)); + | ^~~~~~~~~~~~~ +%Error: t/t_invalid_task_arguments_bad.v:49:23: Function Argument expects 'logic', got 'logic$[]' + : ... note: In instance 't' + 49 | scalar_task(.data(dyn_data)); + | ^~~~~~~~ +%Error: t/t_invalid_task_arguments_bad.v:50:23: Function Argument expects 'logic', got 'logic$[$]' + : ... note: In instance 't' + 50 | scalar_task(.data(queue_data)); + | ^~~~~~~~~~ +%Error: t/t_invalid_task_arguments_bad.v:51:23: Function Argument expects 'logic', got 'logic$[int]' + : ... note: In instance 't' + 51 | scalar_task(.data(assoc_data)); + | ^~~~~~~~~~ +%Error: t/t_invalid_task_arguments_bad.v:52:27: Function Argument expects 'logic[30:0]', got 'logic$[3:0]' + : ... note: In instance 't' + 52 | scalar_vec_task(.data(vec_data)); + | ^~~~~~~~ +%Error: t/t_invalid_task_arguments_bad.v:53:32: Function Argument expects 'logic', got 'logic$[0:9]' + : ... note: In instance 't' + 53 | logical_or(my_signal_a[0], my_signal_b); + | ^~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_invalid_task_arguments_bad.v b/test_regress/t/t_invalid_task_arguments_bad.v index c5d7adaad..93db10419 100644 --- a/test_regress/t/t_invalid_task_arguments_bad.v +++ b/test_regress/t/t_invalid_task_arguments_bad.v @@ -20,12 +20,37 @@ task assoc_task(input logic [30:0] data[int]); $display("%p", data); endtask +task scalar_task(input logic data); + $display("%b", data); +endtask + +task scalar_vec_task(input logic [30:0] data); + $display("%b", data); +endtask + +function logic logical_or(input logic a, b); + return a | b; +endfunction + module t; + logic unpacked_data[3:0]; + logic dyn_data[]; + logic queue_data[$]; + logic assoc_data[int]; + logic vec_data[3:0]; + logic my_signal_a[10]; + logic my_signal_b[10]; initial begin dyn_task(.data($urandom)); unpacked_task(.data($urandom)); queue_task(.data($urandom)); assoc_task(.data($urandom)); + scalar_task(.data(unpacked_data)); + scalar_task(.data(dyn_data)); + scalar_task(.data(queue_data)); + scalar_task(.data(assoc_data)); + scalar_vec_task(.data(vec_data)); + logical_or(my_signal_a[0], my_signal_b); $write("*-* All Finished *-*\n"); $finish; end