diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp --- a/clang/lib/Format/BreakableToken.cpp +++ b/clang/lib/Format/BreakableToken.cpp @@ -102,6 +102,17 @@ static const auto kNumberedListRegexp = llvm::Regex("^[1-9][0-9]?\\."); while (SpaceOffset != StringRef::npos) { + // In C++ with the -Werror=comment option, having multiline comments ( + // two consecutive comment lines, the first ending in `\`) is an + // error. Avoid introducing multiline comments by not allowing a break right + // after '\'. + if (Style.isCpp()) { + StringRef::size_type LastNonBlank = + Text.find_last_not_of(Blanks, SpaceOffset); + if (LastNonBlank != StringRef::npos && Text[LastNonBlank] == '\\') + SpaceOffset = Text.find_last_of(Blanks, LastNonBlank); + } + // Do not split before a number followed by a dot: this would be interpreted // as a numbered list, which would prevent re-flowing in subsequent passes. if (kNumberedListRegexp.match(Text.substr(SpaceOffset).ltrim(Blanks))) diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -745,6 +745,20 @@ getLLVMStyleWithColumns(49))); } +TEST_F(FormatTestComments, DontIntroduceMultilineComments) { + // Avoid introducing a multiline comment by breaking after `\`. + for (int ColumnLimit = 15; ColumnLimit <= 17; ++ColumnLimit) { + EXPECT_EQ( + "// aaaaaaaaaa\n" + "// \\ bb", + format("// aaaaaaaaaa \\ bb", getLLVMStyleWithColumns(ColumnLimit))); + EXPECT_EQ( + "// aaaaaaaaa\n" + "// \\ bb", + format("// aaaaaaaaa \\ bb", getLLVMStyleWithColumns(ColumnLimit))); + } +} + TEST_F(FormatTestComments, DontSplitLineCommentsWithPragmas) { FormatStyle Pragmas = getLLVMStyleWithColumns(30); Pragmas.CommentPragmas = "^ IWYU pragma:";