[PATCH] D36019: [clang-format] Fix bug with ENAS_DontAlign and empty lines

Jacob Bandes-Storch via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 28 14:16:56 PDT 2017


jtbandes created this revision.
Herald added a subscriber: klimek.

This fixes a bug in `ENAS_DontAlign` (introduced in https://reviews.llvm.org/D32733) where blank lines had an EscapedNewlineColumn of 0, causing a subtraction to overflow when converted back to `unsigned` and leading to runaway memory allocation.

This restores the original approach of a separate loop as originally proposed in https://reviews.llvm.org/D32733?vs=97397&id=97404, now with a proper justification :)


https://reviews.llvm.org/D36019

Files:
  lib/Format/WhitespaceManager.cpp
  unittests/Format/FormatTest.cpp


Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -2309,6 +2309,30 @@
   EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();"));
   EXPECT_EQ("/* \\  \\  \\\n */", format("\\\n/* \\  \\  \\\n */"));
   EXPECT_EQ("<a\n\\\\\n>", format("<a\n\\\\\n>"));
+
+  FormatStyle DontAlign = getLLVMStyle();
+  DontAlign.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+  DontAlign.MaxEmptyLinesToKeep = 3;
+  // FIXME: can't use verifyFormat here because the newline before
+  // "public:" is not inserted the first time it's reformatted
+  EXPECT_EQ("#define A \\\n"
+            "  class Foo { \\\n"
+            "    void bar(); \\\n"
+            " \\\n"
+            " \\\n"
+            " \\\n"
+            "  public: \\\n"
+            "    void baz(); \\\n"
+            "  };",
+            format("#define A \\\n"
+                   "  class Foo { \\\n"
+                   "    void bar(); \\\n"
+                   " \\\n"
+                   " \\\n"
+                   " \\\n"
+                   "  public: \\\n"
+                   "    void baz(); \\\n"
+                   "  };", DontAlign));
 }
 
 TEST_F(FormatTest, CalculateSpaceOnConsecutiveLinesInMacro) {
Index: lib/Format/WhitespaceManager.cpp
===================================================================
--- lib/Format/WhitespaceManager.cpp
+++ lib/Format/WhitespaceManager.cpp
@@ -557,9 +557,22 @@
 }
 
 void WhitespaceManager::alignEscapedNewlines() {
-  if (Style.AlignEscapedNewlines == FormatStyle::ENAS_DontAlign)
+  // If we are not aligning escaped newlines, just set EscapedNewlineColumn
+  // to point to the end of each line.
+  if (Style.AlignEscapedNewlines == FormatStyle::ENAS_DontAlign) {
+    bool PreviousContinuerHadNLBefore = false;  // used to detect blank lines
+    for (Change &C : Changes) {
+      if (C.ContinuesPPDirective) {
+        if (C.NewlinesBefore > 0)
+          C.EscapedNewlineColumn =
+            PreviousContinuerHadNLBefore ? 2 : C.PreviousEndOfTokenColumn + 2;
+        PreviousContinuerHadNLBefore = C.NewlinesBefore > 0;
+      }
+    }
     return;
+  }
 
+  // Otherwise, compute the max width and then apply it to all lines.
   bool AlignLeft = Style.AlignEscapedNewlines == FormatStyle::ENAS_Left;
   unsigned MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
   unsigned StartOfMacro = 0;
@@ -644,6 +657,7 @@
                                           unsigned PreviousEndOfTokenColumn,
                                           unsigned EscapedNewlineColumn) {
   if (Newlines > 0) {
+    assert(EscapedNewlineColumn >= 2);
     unsigned Offset =
         std::min<int>(EscapedNewlineColumn - 2, PreviousEndOfTokenColumn);
     for (unsigned i = 0; i < Newlines; ++i) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D36019.108712.patch
Type: text/x-patch
Size: 2855 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170728/aac335ab/attachment.bin>


More information about the cfe-commits mailing list