[cfe-commits] r171495 - in /cfe/trunk: lib/Format/Format.cpp unittests/Format/FormatTest.cpp

Daniel Jasper djasper at google.com
Fri Jan 4 10:52:56 PST 2013


Author: djasper
Date: Fri Jan  4 12:52:56 2013
New Revision: 171495

URL: http://llvm.org/viewvc/llvm-project?rev=171495&view=rev
Log:
Let the formatter ignore UnwrappedLines containing errors.

This prevents code like:

namespace {
class Foo {
  Foo(
  };
}  // comment

from causing segfaults (see llvm.org/PR14774).

Modified:
    cfe/trunk/lib/Format/Format.cpp
    cfe/trunk/unittests/Format/FormatTest.cpp

Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=171495&r1=171494&r2=171495&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Fri Jan  4 12:52:56 2013
@@ -120,7 +120,7 @@
 
     // Check whether the UnwrappedLine can be put onto a single line. If so,
     // this is bound to be the optimal solution (by definition) and we don't
-    // need to analyze the entire solution space. 
+    // need to analyze the entire solution space.
     unsigned Columns = State.Column;
     bool FitsOnALine = true;
     for (unsigned i = 1, n = Line.Tokens.size(); i != n; ++i) {
@@ -535,14 +535,16 @@
           return true;
         }
         if (Tokens[Index].Tok.is(tok::r_paren) ||
-            Tokens[Index].Tok.is(tok::r_square))
+            Tokens[Index].Tok.is(tok::r_square) ||
+            Tokens[Index].Tok.is(tok::r_brace))
           return false;
         if (Tokens[Index].Tok.is(tok::pipepipe) ||
             Tokens[Index].Tok.is(tok::ampamp) ||
             Tokens[Index].Tok.is(tok::question) ||
             Tokens[Index].Tok.is(tok::colon))
           return false;
-        consumeToken();
+        if (!consumeToken())
+          return false;
       }
       return false;
     }
@@ -553,9 +555,11 @@
           next();
           return true;
         }
-        if (Tokens[Index].Tok.is(tok::r_square))
+        if (Tokens[Index].Tok.is(tok::r_square) ||
+            Tokens[Index].Tok.is(tok::r_brace))
+          return false;
+        if (!consumeToken())
           return false;
-        consumeToken();
       }
       return false;
     }
@@ -566,9 +570,11 @@
           next();
           return true;
         }
-        if (Tokens[Index].Tok.is(tok::r_paren))
+        if (Tokens[Index].Tok.is(tok::r_paren) ||
+            Tokens[Index].Tok.is(tok::r_brace))
+          return false;
+        if (!consumeToken())
           return false;
-        consumeToken();
       }
       return false;
     }
@@ -580,7 +586,8 @@
           next();
           return true;
         }
-        consumeToken();
+        if (!consumeToken())
+          return false;
       }
       return false;
     }
@@ -598,19 +605,21 @@
       return false;
     }
 
-    void consumeToken() {
+    bool consumeToken() {
       unsigned CurrentIndex = Index;
       next();
       switch (Tokens[CurrentIndex].Tok.getKind()) {
       case tok::l_paren:
-        parseParens();
+        if (!parseParens())
+          return false;
         if (Index < Tokens.size() && Tokens[Index].Tok.is(tok::colon)) {
           Annotations[Index].Type = TokenAnnotation::TT_CtorInitializerColon;
           next();
         }
         break;
       case tok::l_square:
-        parseSquare();
+        if (!parseSquare())
+          return false;
         break;
       case tok::less:
         if (parseAngle())
@@ -620,6 +629,9 @@
           Index = CurrentIndex + 1;
         }
         break;
+      case tok::r_paren:
+      case tok::r_square:
+        return false;
       case tok::greater:
         Annotations[CurrentIndex].Type = TokenAnnotation::TT_BinaryOperator;
         break;
@@ -647,6 +659,7 @@
       default:
         break;
       }
+      return true;
     }
 
     void parseIncludeDirective() {
@@ -678,14 +691,16 @@
       }
     }
 
-    void parseLine() {
+    bool parseLine() {
       if (Tokens[Index].Tok.is(tok::hash)) {
         parsePreprocessorDirective();
-        return;
+        return true;
       }
       while (Index < Tokens.size()) {
-        consumeToken();
+        if (!consumeToken())
+          return false;
       }
+      return true;
     }
 
     void next() {
@@ -698,14 +713,15 @@
     unsigned Index;
   };
 
-  void annotate() {
+  bool annotate() {
     Annotations.clear();
     for (int i = 0, e = Line.Tokens.size(); i != e; ++i) {
       Annotations.push_back(TokenAnnotation());
     }
 
     AnnotatingParser Parser(Line.Tokens, Annotations);
-    Parser.parseLine();
+    if (!Parser.parseLine())
+      return false;
 
     determineTokenTypes();
     bool IsObjCMethodDecl =
@@ -806,6 +822,7 @@
       if (Annotation.MustBreakBefore)
         Annotation.CanBreakBefore = true;
     }
+    return true;
   }
 
   const std::vector<TokenAnnotation> &getAnnotations() {
@@ -1092,7 +1109,8 @@
         continue;
 
       TokenAnnotator Annotator(TheLine, Style, SourceMgr);
-      Annotator.annotate();
+      if (!Annotator.annotate())
+        return;
       UnwrappedLineFormatter Formatter(Style, SourceMgr, TheLine,
                                        Annotator.getAnnotations(), Replaces,
                                        StructuralError);

Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=171495&r1=171494&r2=171495&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Jan  4 12:52:56 2013
@@ -859,6 +859,13 @@
                "};");
 }
 
+TEST_F(FormatTest, DoesNotTouchUnwrappedLinesWithErrors) {
+  verifyFormat("namespace {\n"
+               "class Foo {\n"
+               "  Foo  ( };\n"
+               "}  // comment");
+}
+
 TEST_F(FormatTest, IncorrectCodeErrorDetection) {
   EXPECT_EQ("{\n{\n}\n", format("{\n{\n}\n"));
   EXPECT_EQ("{\n  {\n}\n", format("{\n  {\n}\n"));





More information about the cfe-commits mailing list