Author: krasimir Date: Tue Jun 12 12:33:15 2018 New Revision: 334527 URL: http://llvm.org/viewvc/llvm-project?rev=334527&view=rev Log: [clang-format] Fix crash while reflowing backslash in comments
Summary: The added test case was currently crashing with an assertion: ``` krasimir@krasimir> cat test.cc ~ // How to run: // bbbbb run \ // rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr \ // <log_file> -- --output_directory="<output_directory>" krasimir@krasimir> ~/work/llvm-build/bin/clang-format test.cc ~ clang-format: /usr/local/google/home/krasimir/work/llvm/tools/clang/lib/Format/WhitespaceManager.cpp:117: void clang::format::WhitespaceManager::calculateLineBreakInformation(): Assertion `PreviousOriginalWhitespaceEndOffset <= OriginalWhitespaceStartOffset' failed. ``` The root cause was that BreakableToken was not considering the case of a reflow between an unescaped newline in a line comment. Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D48089 Modified: cfe/trunk/lib/Format/BreakableToken.cpp cfe/trunk/unittests/Format/FormatTestComments.cpp Modified: cfe/trunk/lib/Format/BreakableToken.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/BreakableToken.cpp?rev=334527&r1=334526&r2=334527&view=diff ============================================================================== --- cfe/trunk/lib/Format/BreakableToken.cpp (original) +++ cfe/trunk/lib/Format/BreakableToken.cpp Tue Jun 12 12:33:15 2018 @@ -789,16 +789,47 @@ BreakableComment::Split BreakableLineCom void BreakableLineCommentSection::reflow(unsigned LineIndex, WhitespaceManager &Whitespaces) const { - // Reflow happens between tokens. Replace the whitespace between the - // tokens by the empty string. - Whitespaces.replaceWhitespace( - *Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0, - /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false); + if (LineIndex > 0 && Tokens[LineIndex] != Tokens[LineIndex - 1]) { + // Reflow happens between tokens. Replace the whitespace between the + // tokens by the empty string. + Whitespaces.replaceWhitespace( + *Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0, + /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false); + } else if (LineIndex > 0) { + // In case we're reflowing after the '\' in: + // + // // line comment \ + // // line 2 + // + // the reflow happens inside the single comment token (it is a single line + // comment with an unescaped newline). + // Replace the whitespace between the '\' and '//' with the empty string. + // + // Offset points to after the '\' relative to start of the token. + unsigned Offset = Lines[LineIndex - 1].data() + + Lines[LineIndex - 1].size() - + tokenAt(LineIndex - 1).TokenText.data(); + // WhitespaceLength is the number of chars between the '\' and the '//' on + // the next line. + unsigned WhitespaceLength = + Lines[LineIndex].data() - tokenAt(LineIndex).TokenText.data() - Offset; + Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex], + Offset, + /*ReplaceChars=*/WhitespaceLength, + /*PreviousPostfix=*/"", + /*CurrentPrefix=*/"", + /*InPPDirective=*/false, + /*Newlines=*/0, + /*Spaces=*/0); + + } // Replace the indent and prefix of the token with the reflow prefix. + unsigned Offset = + Lines[LineIndex].data() - tokenAt(LineIndex).TokenText.data(); unsigned WhitespaceLength = - Content[LineIndex].data() - tokenAt(LineIndex).TokenText.data(); + Content[LineIndex].data() - Lines[LineIndex].data(); Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex], - /*Offset=*/0, + Offset, /*ReplaceChars=*/WhitespaceLength, /*PreviousPostfix=*/"", /*CurrentPrefix=*/ReflowPrefix, Modified: cfe/trunk/unittests/Format/FormatTestComments.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestComments.cpp?rev=334527&r1=334526&r2=334527&view=diff ============================================================================== --- cfe/trunk/unittests/Format/FormatTestComments.cpp (original) +++ cfe/trunk/unittests/Format/FormatTestComments.cpp Tue Jun 12 12:33:15 2018 @@ -3090,6 +3090,21 @@ TEST_F(FormatTestComments, BreaksBeforeT getLLVMStyleWithColumns(23)); } +TEST_F(FormatTestComments, ReflowBackslashCrash) { +// clang-format off + EXPECT_EQ( +"// How to run:\n" +"// bbbbb run \\\n" +"// rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr\n" +"// \\ <log_file> -- --output_directory=\"<output_directory>\"", + format( +"// How to run:\n" +"// bbbbb run \\\n" +"// rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr \\\n" +"// <log_file> -- --output_directory=\"<output_directory>\"")); +// clang-format on +} + } // end namespace } // end namespace format } // end namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits