From 8a24897c13e0b15e76bc49a038986b7d2728fb2a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 12 Jan 2026 19:17:17 -0500 Subject: [PATCH] Fix `foreach` with mid-index empty commas (#6910). Fixes #6910. --- Changes | 1 + src/verilog.y | 11 +++++++---- test_regress/t/t_foreach_noivar.v | 9 +++++++++ test_regress/t/t_foreach_noivar_bad.out | 8 ++++---- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Changes b/Changes index b9bd5e3df..3f93dc295 100644 --- a/Changes +++ b/Changes @@ -33,6 +33,7 @@ Verilator 5.045 devel * Fix segfault in V3Slice (#6899). [Pawel Kojma, Antmicro Ltd.] * Fix signedness of packed array (#6901) (#6902). [Yutetsu TAKATSUKASA] * Fix assignment of queue from unpacked array (#6906). +* Fix `foreach` with mid-index empty commas (#6910). Verilator 5.044 2026-01-01 diff --git a/src/verilog.y b/src/verilog.y index 2e05be5e1..9bff7a54d 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -4053,10 +4053,13 @@ for_step_assignment: // ==IEEE: for_step_assignment ; loop_variables: // IEEE: loop_variables - parseRefBase { $$ = $1; } - | loop_variables ',' parseRefBase { $$ = $1->addNext($3); } - | ',' parseRefBase { $$ = new AstEmpty{$1}; $$->addNext($2); } - | ',' { $$ = new AstEmpty{$1}; } + loop_variableE { $$ = $1; } + | loop_variables ',' loop_variableE { $$ = $1->addNext($3); } + ; + +loop_variableE: // IEEE: part of loop_variables + /* empty */ { $$ = new AstEmpty{CRELINE()}; } + | parseRefBase { $$ = $1; } ; //************************************************ diff --git a/test_regress/t/t_foreach_noivar.v b/test_regress/t/t_foreach_noivar.v index 7f5606605..cb5f99112 100644 --- a/test_regress/t/t_foreach_noivar.v +++ b/test_regress/t/t_foreach_noivar.v @@ -7,12 +7,15 @@ // verilog_format: off `define stop $stop `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +`define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); // verilog_format: on module t; reg [63:0] sum; // Checked not in objects reg [2:1][4:3] array[5:6][7:8]; + bit [3:2][2:1] array2[5:4][2]; + string did; initial begin sum = 0; @@ -27,6 +30,12 @@ module t; end `checkh(sum, 0); + foreach (array2[i, j,, l]) begin + did = {did, $sformatf("; %0d,%0d,,%0d", i, j, l)}; + end + `checks(did, "; 5,0,,2; 5,0,,1; 5,1,,2; 5,1,,1; 4,0,,2; 4,0,,1; 4,1,,2; 4,1,,1"); + $finish; + $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_foreach_noivar_bad.out b/test_regress/t/t_foreach_noivar_bad.out index 0b411572c..75f0d451d 100644 --- a/test_regress/t/t_foreach_noivar_bad.out +++ b/test_regress/t/t_foreach_noivar_bad.out @@ -1,11 +1,11 @@ -%Warning-NOEFFECT: t/t_foreach_noivar.v:19:5: foreach with no loop variable has no effect +%Warning-NOEFFECT: t/t_foreach_noivar.v:22:5: foreach with no loop variable has no effect : ... note: In instance 't' - 19 | foreach (array[]) begin + 22 | foreach (array[]) begin | ^~~~~~~ ... For warning description see https://verilator.org/warn/NOEFFECT?v=latest ... Use "/* verilator lint_off NOEFFECT */" and lint_on around source to disable this message. -%Warning-NOEFFECT: t/t_foreach_noivar.v:25:5: foreach with no loop variable has no effect +%Warning-NOEFFECT: t/t_foreach_noivar.v:28:5: foreach with no loop variable has no effect : ... note: In instance 't' - 25 | foreach (array[,,]) begin + 28 | foreach (array[,,]) begin | ^~~~~~~ %Error: Exiting due to