r216518 - PR20760: Don't assert (and produce better diagnostics) if a default initializer

Richard Smith richard-llvm at metafoo.co.uk
Tue Aug 26 20:23:12 PDT 2014


Author: rsmith
Date: Tue Aug 26 22:23:12 2014
New Revision: 216518

URL: http://llvm.org/viewvc/llvm-project?rev=216518&view=rev
Log:
PR20760: Don't assert (and produce better diagnostics) if a default initializer
contains an unmatched closing bracket token.

Modified:
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/test/Parser/cxx-class.cpp

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=216518&r1=216517&r2=216518&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Tue Aug 26 22:23:12 2014
@@ -540,11 +540,13 @@ void Parser::ParseLexedMemberInitializer
 
   // The next token should be our artificial terminating EOF token.
   if (Tok.isNot(tok::eof)) {
-    SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
-    if (!EndLoc.isValid())
-      EndLoc = Tok.getLocation();
-    // No fixit; we can't recover as if there were a semicolon here.
-    Diag(EndLoc, diag::err_expected_semi_decl_list);
+    if (!Init.isInvalid()) {
+      SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation);
+      if (!EndLoc.isValid())
+        EndLoc = Tok.getLocation();
+      // No fixit; we can't recover as if there were a semicolon here.
+      Diag(EndLoc, diag::err_expected_semi_decl_list);
+    }
 
     // Consume tokens until we hit the artificial EOF.
     while (Tok.isNot(tok::eof))
@@ -891,11 +893,13 @@ private:
 /// ConsumeAndStoreInitializer - Consume and store the token at the passed token
 /// container until the end of the current initializer expression (either a
 /// default argument or an in-class initializer for a non-static data member).
-/// The final token is not consumed.
+///
+/// Returns \c true if we reached the end of something initializer-shaped,
+/// \c false if we bailed out.
 bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,
                                         CachedInitKind CIK) {
   // We always want this function to consume at least one token if not at EOF.
-  bool IsFirstTokenConsumed = true;
+  bool IsFirstToken = true;
 
   // Number of possible unclosed <s we've seen so far. These might be templates,
   // and might not, but if there were none of them (or we know for sure that
@@ -1064,21 +1068,28 @@ bool Parser::ConsumeAndStoreInitializer(
     // Since the user wasn't looking for this token (if they were, it would
     // already be handled), this isn't balanced.  If there is a LHS token at a
     // higher level, we will assume that this matches the unbalanced token
-    // and return it.  Otherwise, this is a spurious RHS token, which we skip.
+    // and return it.  Otherwise, this is a spurious RHS token, which we
+    // consume and pass on to downstream code to diagnose.
     case tok::r_paren:
       if (CIK == CIK_DefaultArgument)
         return true; // End of the default argument.
-      if (ParenCount && !IsFirstTokenConsumed)
-        return false;  // Matches something.
-      goto consume_token;
+      if (ParenCount && !IsFirstToken)
+        return false;
+      Toks.push_back(Tok);
+      ConsumeParen();
+      continue;
     case tok::r_square:
-      if (BracketCount && !IsFirstTokenConsumed)
-        return false;  // Matches something.
-      goto consume_token;
+      if (BracketCount && !IsFirstToken)
+        return false;
+      Toks.push_back(Tok);
+      ConsumeBracket();
+      continue;
     case tok::r_brace:
-      if (BraceCount && !IsFirstTokenConsumed)
-        return false;  // Matches something.
-      goto consume_token;
+      if (BraceCount && !IsFirstToken)
+        return false;
+      Toks.push_back(Tok);
+      ConsumeBrace();
+      continue;
 
     case tok::code_completion:
       Toks.push_back(Tok);
@@ -1103,6 +1114,6 @@ bool Parser::ConsumeAndStoreInitializer(
       ConsumeToken();
       break;
     }
-    IsFirstTokenConsumed = false;
+    IsFirstToken = false;
   }
 }

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=216518&r1=216517&r2=216518&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Aug 26 22:23:12 2014
@@ -5438,8 +5438,7 @@ void Parser::ParseParameterDeclarationCl
 
       // Inform the actions module about the parameter declarator, so it gets
       // added to the current scope.
-      Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), 
-                                                       ParmDeclarator);
+      Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator);
       // Parse the default argument, if any. We parse the default
       // arguments in all dialects; the semantic analysis in
       // ActOnParamDefaultArgument will reject the default argument in

Modified: cfe/trunk/test/Parser/cxx-class.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-class.cpp?rev=216518&r1=216517&r2=216518&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-class.cpp (original)
+++ cfe/trunk/test/Parser/cxx-class.cpp Tue Aug 26 22:23:12 2014
@@ -149,6 +149,17 @@ namespace BadFriend {
   };
 }
 
+class PR20760_a {
+  int a = ); // expected-warning {{extension}} expected-error {{expected expression}}
+  int b = }; // expected-warning {{extension}} expected-error {{expected expression}}
+  int c = ]; // expected-warning {{extension}} expected-error {{expected expression}}
+};
+class PR20760_b {
+  int d = d); // expected-warning {{extension}} expected-error {{expected ';'}}
+  int e = d]; // expected-warning {{extension}} expected-error {{expected ';'}}
+  int f = d // expected-warning {{extension}} expected-error {{expected ';'}}
+};
+
 // 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}}





More information about the cfe-commits mailing list