PR20760: Don't assert (and produce better diagnostics) if a default initializer
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 27 Aug 2014 03:23:12 +0000 (03:23 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 27 Aug 2014 03:23:12 +0000 (03:23 +0000)
contains an unmatched closing bracket token.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216518 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseCXXInlineMethods.cpp
lib/Parse/ParseDecl.cpp
test/Parser/cxx-class.cpp

index 55caa5e59f6e2ec11b78a051c4333298a3697f62..3571d5ab41351db1704e76bb0d6096456ed9d993 100644 (file)
@@ -540,11 +540,13 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
 
   // 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(CachedTokens &Toks,
     // 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(CachedTokens &Toks,
       ConsumeToken();
       break;
     }
-    IsFirstTokenConsumed = false;
+    IsFirstToken = false;
   }
 }
index 7132b4aab1952eb2e5ff02021408e754b7ea715d..b51b742f9da25282710bc1ee648d6d5e31594cb0 100644 (file)
@@ -5438,8 +5438,7 @@ void Parser::ParseParameterDeclarationClause(
 
       // 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
index 8698454968eb95c38327683600a10131955d20de..69776f4d42217d686e023d6f7dbfbae62e039eec 100644 (file)
@@ -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}}