]> granicus.if.org Git - clang/commitdiff
Fix crash-on-invalid, improve error recovery, and test coverage for missing colon...
authorDavid Blaikie <dblaikie@gmail.com>
Thu, 13 Oct 2011 06:08:43 +0000 (06:08 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Thu, 13 Oct 2011 06:08:43 +0000 (06:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141852 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDeclCXX.cpp
test/Parser/cxx-class.cpp

index 51cdf6b64ec86464b705ae98e591ea974621c33e..decb7f9ec5f493cad3a0a162ccdfb1475c0c8af8 100644 (file)
@@ -2135,12 +2135,23 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
         // Current token is a C++ access specifier.
         CurAS = AS;
         SourceLocation ASLoc = Tok.getLocation();
+        unsigned TokLength = Tok.getLength();
         ConsumeToken();
-        if (Tok.is(tok::colon))
-          Actions.ActOnAccessSpecifier(AS, ASLoc, Tok.getLocation());
-        else
-          Diag(Tok, diag::err_expected_colon);
-        ConsumeToken();
+        SourceLocation EndLoc;
+        if (Tok.is(tok::colon)) {
+          EndLoc = Tok.getLocation();
+          ConsumeToken();
+        } else if (Tok.is(tok::semi)) {
+          EndLoc = Tok.getLocation();
+          ConsumeToken();
+          Diag(EndLoc, diag::err_expected_colon) 
+            << FixItHint::CreateReplacement(EndLoc, ":");
+        } else {
+          EndLoc = ASLoc.getLocWithOffset(TokLength);
+          Diag(EndLoc, diag::err_expected_colon) 
+            << FixItHint::CreateInsertion(EndLoc, ":");
+        }
+        Actions.ActOnAccessSpecifier(AS, ASLoc, EndLoc);
         continue;
       }
 
index f863bd198e507acda27fb9e001bb05cf753abbbf..1c0d862b3096a30ec312a905fd8d9d6b092a819e 100644 (file)
@@ -40,3 +40,20 @@ typedef union {
   } y;
 } bug3177;
 
+// check that we don't consume the token after the access specifier 
+// when it's not a colon
+class D {
+public // expected-error{{expected ':'}}
+  int i;
+};
+
+// consume the token after the access specifier if it's a semicolon 
+// that was meant to be a colon
+class E {
+public; // expected-error{{expected ':'}}
+  int i;
+};
+
+// PR11109 must appear at the end of the source file
+class pr11109r3 { // expected-note{{to match this '{'}}
+  public // expected-error{{expected ':'}} expected-error{{expected '}'}} expected-error{{expected ';' after class}}