summaryrefslogtreecommitdiffstats
path: root/clang/lib/Format
diff options
context:
space:
mode:
authorKrasimir Georgiev <krasimir@google.com>2018-06-12 19:33:15 +0000
committerKrasimir Georgiev <krasimir@google.com>2018-06-12 19:33:15 +0000
commit4fc55a76b8d28335d2b57fe083bcc165c0061dab (patch)
treeacb49e459329f6a9d632bb7cb61835a7e51a097f /clang/lib/Format
parent4872750dd38110a8f68eb70c39c1650d410b8564 (diff)
downloadbcm5719-llvm-4fc55a76b8d28335d2b57fe083bcc165c0061dab.tar.gz
bcm5719-llvm-4fc55a76b8d28335d2b57fe083bcc165c0061dab.zip
[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 llvm-svn: 334527
Diffstat (limited to 'clang/lib/Format')
-rw-r--r--clang/lib/Format/BreakableToken.cpp45
1 files changed, 38 insertions, 7 deletions
diff --git a/clang/lib/Format/BreakableToken.cpp b/clang/lib/Format/BreakableToken.cpp
index f727f8ddf89..cc68f70100e 100644
--- a/clang/lib/Format/BreakableToken.cpp
+++ b/clang/lib/Format/BreakableToken.cpp
@@ -789,16 +789,47 @@ BreakableComment::Split BreakableLineCommentSection::getReflowSplit(
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,
OpenPOWER on IntegriCloud