Merge pull request #2606 from kbrunham-intel/fix/2605
Fix timescale CRLF // comments leaving CR in the token
diff --git a/verible/verilog/formatting/formatter_issue_regression_test.cc b/verible/verilog/formatting/formatter_issue_regression_test.cc
index f156371..f27b898 100644
--- a/verible/verilog/formatting/formatter_issue_regression_test.cc
+++ b/verible/verilog/formatting/formatter_issue_regression_test.cc
@@ -109,6 +109,43 @@
EXPECT_THAT(stream.str(), testing::HasSubstr("`TOKEN_BYTE"));
}
+// Regression for https://github.com/chipsalliance/verible/issues/2605:
+// TIMESCALE_DIRECTIVE's EndOfLineComment handler used yyless(yyleng-1),
+// which left `\r` in the comment token for CRLF files. Emitting that token
+// plus a CRLF terminator produced `\r\r\n` and failed FormatEquivalent.
+TEST(FormatterEndToEndTest, TimescaleCrlfEolComment) {
+ static constexpr FormatterTestCase kTestCases[] = {
+ // Next-line `//` comment after `timescale (the reduced issue case).
+ {"`timescale 1 ps / 1 ps\r\n"
+ "// hello\r\n"
+ "module m;\r\n"
+ "endmodule\r\n",
+ "`timescale 1 ps / 1 ps\r\n"
+ "// hello\r\n"
+ "module m;\r\n"
+ "endmodule\r\n"},
+ // Same-line `//` comment on the `timescale directive.
+ {"`timescale 1 ps / 1 ps // hello\r\n"
+ "module m;\r\n"
+ "endmodule\r\n",
+ "`timescale 1 ps / 1 ps // hello\r\n"
+ "module m;\r\n"
+ "endmodule\r\n"},
+ // LF control: this path already passed lexical verification.
+ {"`timescale 1 ps / 1 ps\n"
+ "// hello\n"
+ "module m;\n"
+ "endmodule\n",
+ "`timescale 1 ps / 1 ps\n"
+ "// hello\n"
+ "module m;\n"
+ "endmodule\n"},
+ };
+ FormatStyle style;
+ style.line_terminator = verible::LineTerminatorOptionStyle::kAuto;
+ RunFormatterTestCases(style, kTestCases);
+}
+
// Regression for https://github.com/chipsalliance/verible/issues/2542:
// Continuation EOL comments after a wrapped assign must keep a stable column
// across re-format (convergence).
diff --git a/verible/verilog/parser/verilog-lexer_test.cc b/verible/verilog/parser/verilog-lexer_test.cc
index e23b911..7e7c54b 100644
--- a/verible/verilog/parser/verilog-lexer_test.cc
+++ b/verible/verilog/parser/verilog-lexer_test.cc
@@ -2041,6 +2041,24 @@
{'/', "/"},
{TK_TimeLiteral, "1ps"},
{TK_NEWLINE, "\n"}},
+ // Issue #2605: CRLF `//` comments in TIMESCALE_DIRECTIVE must not keep
+ // `\r`.
+ {{DR_timescale, "`timescale"},
+ {TK_SPACE, " "},
+ {TK_TimeLiteral, "1ps"},
+ {'/', "/"},
+ {TK_TimeLiteral, "1ps"},
+ {TK_NEWLINE, "\r\n"},
+ {TK_EOL_COMMENT, "// hello"},
+ {TK_NEWLINE, "\r\n"}},
+ {{DR_timescale, "`timescale"},
+ {TK_SPACE, " "},
+ {TK_TimeLiteral, "1ps"},
+ {'/', "/"},
+ {TK_TimeLiteral, "1ps"},
+ {TK_SPACE, " "},
+ {TK_EOL_COMMENT, "// hello"},
+ {TK_NEWLINE, "\r\n"}},
// TODO(b/134180314): lexer current drops tokens from pragma sections,
// but instead emit the tokens and filter them out.
// {{DR_pragma, "`pragma"}, " fragma", {TK_NEWLINE, "\n"}},
diff --git a/verible/verilog/parser/verilog.lex b/verible/verilog/parser/verilog.lex
index 3afd55e..388d209 100644
--- a/verible/verilog/parser/verilog.lex
+++ b/verible/verilog/parser/verilog.lex
@@ -990,7 +990,13 @@
return TK_COMMENT_BLOCK;
}
{EndOfLineComment} {
- yyless(yyleng-1); /* return \n to input stream */
+ // Match IN_EOL_COMMENT: CRLF is a two-character terminator. Using
+ // yyless(yyleng-1) left `\r` in the comment token, so the formatter
+ // emitted `\r\r\n` after `timescale comments (issue #2605, PR #2371).
+ if (yyleng >= 2 && yytext[yyleng - 2] == '\r')
+ yyless(yyleng - 2); /* return \r\n to input stream */
+ else
+ yyless(yyleng - 1); /* return \n to input stream */
UpdateLocation();
return TK_EOL_COMMENT;
}