diff --git a/elaborate.cc b/elaborate.cc index 1ea15f452..695ddf5fd 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -5379,8 +5379,6 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope, << "Handle as array with static dimensions." << endl; } - ivl_assert(*this, index_vars_.size() > 0); - NetProc*sub; if (statement_) sub = statement_->elaborate(des, scope); @@ -5390,7 +5388,7 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope, if (index_vars_.size() > dims.size()) { delete sub; - cerr << get_fileline() << ": error: Number of foreach loop indices" + cerr << get_fileline() << ": error: Number of foreach loop variables" << "(" << index_vars_.size() << ") must not exceed number of " << "array dimensions (" << dims.size() << ")." << endl; des->errors++; @@ -5400,6 +5398,11 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope, for (int idx_idx = index_vars_.size()-1 ; idx_idx >= 0 ; idx_idx -= 1) { const netrange_t&idx_range = dims[idx_idx]; + // It is possible to skip dimensions by not providing a identifier + // name for it. E.g. `int x[1][2][3]; foreach(x[a,,b]) ...` + if (index_vars_[idx_idx].nil()) + continue; + // Get the $high and $low constant values for this slice // of the array. NetEConst*hig_expr = make_const_val_s(idx_range.get_msb()); @@ -5438,7 +5441,13 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope, sub = stmt; } - return stmt? stmt : sub; + // If there are no loop variables elide the whole block + if (!stmt) { + delete sub; + return new NetBlock(NetBlock::SEQU, 0); + } + + return stmt; } /* diff --git a/parse.y b/parse.y index a4d427704..11de7ec7c 100644 --- a/parse.y +++ b/parse.y @@ -1799,12 +1799,22 @@ loop_variables /* IEEE1800-2005: A.6.8 */ delete[]$3; $$ = tmp; } + | loop_variables ',' + { std::list*tmp = $1; + tmp->push_back(perm_string()); + $$ = tmp; + } | IDENTIFIER { std::list*tmp = new std::list; tmp->push_back(lex_strings.make($1)); delete[]$1; $$ = tmp; } + | + { std::list*tmp = new std::list; + tmp->push_back(perm_string()); + $$ = tmp; + } ; method_qualifier /* IEEE1800-2005: A.1.8 */ diff --git a/pform.cc b/pform.cc index 7405a91c9..535145b05 100644 --- a/pform.cc +++ b/pform.cc @@ -994,6 +994,8 @@ void pform_make_foreach_declarations(const struct vlltype&loc, listassign_list; for (list::const_iterator cur = loop_vars->begin() ; cur != loop_vars->end() ; ++ cur) { + if (cur->nil()) + continue; decl_assignment_t*tmp_assign = new decl_assignment_t; tmp_assign->name = lex_strings.make(*cur); assign_list.push_back(tmp_assign);