Merge origin/master into fix/2605 Resolve the issue-regression conflict by placing the #2605 test after the macro-equivalence regression, away from other open PR tests.
diff --git a/verible/verilog/formatting/BUILD b/verible/verilog/formatting/BUILD index 6e4782e..491a5cf 100644 --- a/verible/verilog/formatting/BUILD +++ b/verible/verilog/formatting/BUILD
@@ -301,6 +301,7 @@ ":format-style", ":formatter", ":formatter-test-utils", + "//verible/common/formatting:basic-format-style", "//verible/common/util:logging", "@googletest//:gtest", "@googletest//:gtest_main",
diff --git a/verible/verilog/formatting/formatter_issue_regression_test.cc b/verible/verilog/formatting/formatter_issue_regression_test.cc index 9490a88..de84377 100644 --- a/verible/verilog/formatting/formatter_issue_regression_test.cc +++ b/verible/verilog/formatting/formatter_issue_regression_test.cc
@@ -91,6 +91,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 b1f3788..23d8cda 100644 --- a/verible/verilog/parser/verilog-lexer_test.cc +++ b/verible/verilog/parser/verilog-lexer_test.cc
@@ -2035,6 +2035,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 759fcc2..5c4cf3b 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; }