Merge pull request #2585 from EylonKrause/fix-forspec-attribute-crash
formatter: avoid crash on attribute instance in for-loop header
diff --git a/verible/verilog/formatting/formatter_test.cc b/verible/verilog/formatting/formatter_test.cc
index c9b1579..bd0f775 100644
--- a/verible/verilog/formatting/formatter_test.cc
+++ b/verible/verilog/formatting/formatter_test.cc
@@ -4730,6 +4730,15 @@
" for (int i = 0; i < f(m); i--) begin\n"
" end\n"
"endfunction\n"},
+ {// for loop with an attribute instance in the initializer.
+ // Regression: this used to abort with a CHECK failure while reshaping
+ // the kForSpec partitions when an attribute appears in the header.
+ "module m; initial for(int i=0(* a *);i<4;i++) x=i; endmodule",
+ "module m;\n"
+ " initial\n"
+ " for (int i = 0 (* a *); i < 4; i++)\n"
+ " x = i;\n"
+ "endmodule\n"},
{// forever loop
"function\nvoid\tforevah;forever begin "
"++k\n;end endfunction\n",
diff --git a/verible/verilog/formatting/tree-unwrapper.cc b/verible/verilog/formatting/tree-unwrapper.cc
index bc1af07..2286f8c 100644
--- a/verible/verilog/formatting/tree-unwrapper.cc
+++ b/verible/verilog/formatting/tree-unwrapper.cc
@@ -2991,10 +2991,15 @@
auto &children = partition.Children();
const auto iter1 = std::find_if(children.begin(), children.end(),
PartitionStartsWithSemicolon);
- CHECK(iter1 != children.end());
+ // An attribute instance ((* ... *)) in the for-loop header can change
+ // the partition structure so that the expected semicolon-leading
+ // partitions are not present. When they are missing, leave the
+ // partitions unreshaped rather than aborting (avoids a CHECK-failure
+ // crash on attributed/unusual for-headers).
+ if (iter1 == children.end()) break;
const auto iter2 =
std::find_if(iter1 + 1, children.end(), PartitionStartsWithSemicolon);
- CHECK(iter2 != children.end());
+ if (iter2 == children.end()) break;
const int dist1 = std::distance(children.begin(), iter1);
const int dist2 = std::distance(children.begin(), iter2);
VLOG(4) << "kForSpec got ';' at child " << dist1 << " and " << dist2;