[cfe-commits] r151130 - in /cfe/trunk: lib/Parse/ParseCXXInlineMethods.cpp test/CXX/temp/temp.decls/temp.variadic/p4.cpp test/SemaCXX/PR9461.cpp test/SemaCXX/constructor-initializer.cpp

Eli Friedman eli.friedman at gmail.com
Tue Feb 21 20:49:04 PST 2012


Author: efriedma
Date: Tue Feb 21 22:49:04 2012
New Revision: 151130

URL: http://llvm.org/viewvc/llvm-project?rev=151130&view=rev
Log:
Improve diagnostics a bit for bad member initializers, and fix an obscure bug involving packs.  Fixes PR12049.


Modified:
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
    cfe/trunk/test/SemaCXX/PR9461.cpp
    cfe/trunk/test/SemaCXX/constructor-initializer.cpp

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=151130&r1=151129&r2=151130&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Tue Feb 21 22:49:04 2012
@@ -145,16 +145,14 @@
   // function body.
   if (ConsumeAndStoreFunctionPrologue(Toks)) {
     // We didn't find the left-brace we expected after the
-    // constructor initializer.
-    if (Tok.is(tok::semi)) {
-      // We found a semicolon; complain, consume the semicolon, and
-      // don't try to parse this method later.
-      Diag(Tok.getLocation(), diag::err_expected_lbrace);
-      ConsumeAnyToken();
-      delete getCurrentClass().LateParsedDeclarations.back();
-      getCurrentClass().LateParsedDeclarations.pop_back();
-      return FnD;
-    }
+    // constructor initializer; we already printed an error, and it's likely
+    // impossible to recover, so don't try to parse this method later.
+    // If we stopped at a semicolon, consume it to avoid an extra warning.
+     if (Tok.is(tok::semi))
+      ConsumeToken();
+    delete getCurrentClass().LateParsedDeclarations.back();
+    getCurrentClass().LateParsedDeclarations.pop_back();
+    return FnD;
   } else {
     // Consume everything up to (and including) the matching right brace.
     ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
@@ -606,6 +604,7 @@
     Toks.push_back(Tok);
     ConsumeToken();
   }
+  bool ReadInitializer = false;
   if (Tok.is(tok::colon)) {
     // Initializers can contain braces too.
     Toks.push_back(Tok);
@@ -613,37 +612,52 @@
 
     while (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) {
       if (Tok.is(tok::eof) || Tok.is(tok::semi))
-        return true;
+        return Diag(Tok.getLocation(), diag::err_expected_lbrace);
 
       // Grab the identifier.
       if (!ConsumeAndStoreUntil(tok::l_paren, tok::l_brace, Toks,
                                 /*StopAtSemi=*/true,
                                 /*ConsumeFinalToken=*/false))
-        return true;
+        return Diag(Tok.getLocation(), diag::err_expected_lparen);
 
       tok::TokenKind kind = Tok.getKind();
       Toks.push_back(Tok);
-      if (kind == tok::l_paren)
+      bool IsLParen = (kind == tok::l_paren);
+      SourceLocation LOpen = Tok.getLocation();
+
+      if (IsLParen) {
         ConsumeParen();
-      else {
+      } else {
         assert(kind == tok::l_brace && "Must be left paren or brace here.");
         ConsumeBrace();
         // In C++03, this has to be the start of the function body, which
-        // means the initializer is malformed.
+        // means the initializer is malformed; we'll diagnose it later.
         if (!getLang().CPlusPlus0x)
           return false;
       }
 
       // Grab the initializer
-      if (!ConsumeAndStoreUntil(kind == tok::l_paren ? tok::r_paren :
-                                                       tok::r_brace,
-                                Toks, /*StopAtSemi=*/true))
+      if (!ConsumeAndStoreUntil(IsLParen ? tok::r_paren : tok::r_brace,
+                                Toks, /*StopAtSemi=*/true)) {
+        Diag(Tok, IsLParen ? diag::err_expected_rparen :
+                             diag::err_expected_rbrace);
+        Diag(LOpen, diag::note_matching) << (IsLParen ? "(" : "{");
         return true;
+      }
+
+      // Grab pack ellipsis, if present
+      if (Tok.is(tok::ellipsis)) {
+        Toks.push_back(Tok);
+        ConsumeToken();
+      }
 
       // Grab the separating comma, if any.
       if (Tok.is(tok::comma)) {
         Toks.push_back(Tok);
         ConsumeToken();
+      } else if (Tok.isNot(tok::l_brace)) {
+        ReadInitializer = true;
+        break;
       }
     }
   }
@@ -651,11 +665,14 @@
   // Grab any remaining garbage to be diagnosed later. We stop when we reach a
   // brace: an opening one is the function body, while a closing one probably
   // means we've reached the end of the class.
-  if (!ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,
-                            /*StopAtSemi=*/true, /*ConsumeFinalToken=*/false))
-    return true;
-  if(Tok.isNot(tok::l_brace))
-    return true;
+  ConsumeAndStoreUntil(tok::l_brace, tok::r_brace, Toks,
+                       /*StopAtSemi=*/true,
+                       /*ConsumeFinalToken=*/false);
+  if (Tok.isNot(tok::l_brace)) {
+    if (ReadInitializer)
+      return Diag(Tok.getLocation(), diag::err_expected_lbrace_or_comma);
+    return Diag(Tok.getLocation(), diag::err_expected_lbrace);
+  }
 
   Toks.push_back(Tok);
   ConsumeBrace();

Modified: cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp?rev=151130&r1=151129&r2=151130&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.variadic/p4.cpp Tue Feb 21 22:49:04 2012
@@ -91,6 +91,16 @@
   X() : member()... { } // expected-error{{pack expansion for initialization of member 'member'}}
 };
 
+// There was a bug in the delayed parsing code for the
+// following case.
+template<typename ...T>
+struct DelayedParseTest : T...
+{
+  int a;
+  DelayedParseTest(T... i) : T{i}..., a{10} {}
+};
+
+
 // In a template-argument-list (14.3); the pattern is a template-argument.
 template<typename ...Types>
 struct tuple_of_refs {

Modified: cfe/trunk/test/SemaCXX/PR9461.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR9461.cpp?rev=151130&r1=151129&r2=151130&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/PR9461.cpp (original)
+++ cfe/trunk/test/SemaCXX/PR9461.cpp Tue Feb 21 22:49:04 2012
@@ -26,7 +26,7 @@
 :us(_S_construct)
 {string a;}
 
-struct runtime_error{runtime_error(string);}; // expected-note 2 {{candidate constructor}}
+struct runtime_error{runtime_error(string);};
 
-struct system_error:runtime_error{ // expected-note {{to match}} expected-note {{specified here}}
-system_error():time_error("" // expected-error 4 {{expected}} expected-error {{initializer}} expected-note {{to match}} expected-error {{no matching constructor}}
+struct system_error:runtime_error{ // expected-note {{to match}}
+system_error():time_error("" // expected-error 3 {{expected}} expected-note {{to match}}

Modified: cfe/trunk/test/SemaCXX/constructor-initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constructor-initializer.cpp?rev=151130&r1=151129&r2=151130&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constructor-initializer.cpp (original)
+++ cfe/trunk/test/SemaCXX/constructor-initializer.cpp Tue Feb 21 22:49:04 2012
@@ -268,3 +268,15 @@
 };
 
 }
+
+namespace PR12049 {
+  int function();
+
+  class Class
+  {
+  public:
+      Class() : member(function() {} // expected-note {{to match this '('}}
+
+      int member; // expected-error {{expected ')'}}
+  };
+}





More information about the cfe-commits mailing list