]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/45332 (Generate clear diagnostics when a terminating semicolon is missing...
authorNathan Froyd <froydnj@codesourcery.com>
Sat, 6 Nov 2010 18:41:57 +0000 (18:41 +0000)
committerNathan Froyd <froydnj@gcc.gnu.org>
Sat, 6 Nov 2010 18:41:57 +0000 (18:41 +0000)
gcc/cp/
PR c++/45332
* parser.c (cp_lexer_previous_token): New function.
(cp_parser_member_declaration): Use previous token for error
messages.  Assume semicolon presence rather than grovelling for
the next one.

gcc/testsuite/
PR c++/45332
* g++.dg/parse/semicolon2.C: New testcase.
* g++.dg/ext/asmspec1.C: Adjust.
* g++.dg/init/new13.C: Adjust.
* g++.dg/parse/ctor5.C: Adjust.

From-SVN: r166406

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/asmspec1.C
gcc/testsuite/g++.dg/init/new13.C
gcc/testsuite/g++.dg/parse/ctor5.C
gcc/testsuite/g++.dg/parse/semicolon2.C [new file with mode: 0644]

index bfa4af439166dd346e8a1abf9be0011d797c0acc..784f3aab15d263885224460a250d01435d63eabd 100644 (file)
@@ -1,3 +1,11 @@
+2010-11-06  Nathan Froyd  <froydnj@codesourcery.com>
+
+       PR c++/45332
+       * parser.c (cp_lexer_previous_token): New function.
+       (cp_parser_member_declaration): Use previous token for error
+       messages.  Assume semicolon presence rather than grovelling for
+       the next one.
+
 2010-11-06  Joern Rennecke  <amylaar@spamcop.net>
 
        PR middle-end/46314
index 6302864fd978599e553cfc2258471d463ff5e0d3..6a9e4d7b981fe1864f3e800edef57e45ed0f05a1 100644 (file)
@@ -502,6 +502,19 @@ cp_lexer_token_at (cp_lexer *lexer ATTRIBUTE_UNUSED, cp_token_position pos)
   return pos;
 }
 
+static inline cp_token *
+cp_lexer_previous_token (cp_lexer *lexer)
+{
+  cp_token_position tp;
+
+  if (lexer->next_token == &eof_token)
+    tp = lexer->last_token - 1;
+  else
+    tp = cp_lexer_token_position (lexer, true);
+
+  return cp_lexer_token_at (lexer, tp);
+}
+
 /* nonzero if we are presently saving tokens.  */
 
 static inline int
@@ -17627,6 +17640,8 @@ cp_parser_member_declaration (cp_parser* parser)
     }
   else
     {
+      bool assume_semicolon = false;
+
       /* See if these declarations will be friends.  */
       friend_p = cp_parser_friend_p (&decl_specifiers);
 
@@ -17820,11 +17835,18 @@ cp_parser_member_declaration (cp_parser* parser)
          else if (cp_lexer_next_token_is_not (parser->lexer,
                                               CPP_SEMICOLON))
            {
-             cp_parser_error (parser, "expected %<;%>");
-             /* Skip tokens until we find a `;'.  */
-             cp_parser_skip_to_end_of_statement (parser);
+             /* The next token might be a ways away from where the
+                actual semicolon is missing.  Find the previous token
+                and use that for our error position.  */
+             cp_token *token = cp_lexer_previous_token (parser->lexer);
+             error_at (token->location,
+                       "expected %<;%> at end of member declaration");
 
-             break;
+             /* Assume that the user meant to provide a semicolon.  If
+                we were to cp_parser_skip_to_end_of_statement, we might
+                skip to a semicolon inside a member function definition
+                and issue nonsensical error messages.  */
+             assume_semicolon = true;
            }
 
          if (decl)
@@ -17836,6 +17858,9 @@ cp_parser_member_declaration (cp_parser* parser)
              if (TREE_CODE (decl) == FUNCTION_DECL)
                cp_parser_save_default_args (parser, decl);
            }
+
+         if (assume_semicolon)
+           return;
        }
     }
 
index 4577eb26dfaeac1b767f92c8d981e24f06420562..911ba14316297ff4a5d67790edd89a95f0fc9205 100644 (file)
@@ -1,3 +1,11 @@
+2010-11-06  Nathan Froyd  <froydnj@codesourcery.com>
+
+       PR c++/45332
+       * g++.dg/parse/semicolon2.C: New testcase.
+       * g++.dg/ext/asmspec1.C: Adjust.
+       * g++.dg/init/new13.C: Adjust.
+       * g++.dg/parse/ctor5.C: Adjust.
+
 2010-11-06  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/46330
index 3df2483ad53718f89bcf11d1f1015a2b5796b25c..0661136feccec34222072aea1d19773fbeeedf61 100644 (file)
@@ -3,6 +3,6 @@
 
 struct A
 {
-  int i __asm__(int);         // { dg-error "before" }
-  static int j __asm__(int);  // { dg-error "before" }
+  int i __asm__(int);         // { dg-error "expected" }
+  static int j __asm__(int);  // { dg-error "expected" }
 };
index 3563c48808fcff8ba4e42ab1aeb5c20e877ec843..2ced6e3fe020107f5a111b9c5a792fa083b816e0 100644 (file)
@@ -5,7 +5,7 @@
 
 struct A
 {
-  void* operator new(__SIZE_TYPE__) throw(X);  // { dg-error "" }
+  void* operator new(__SIZE_TYPE__) throw(X);  // { dg-error "expected|type" }
 };
 
-A* p = new A;                                  // { dg-error "no suitable" }
+A* p = new A;
index 819458598a3c933d4cc873cf082472eb07ae4764..3ea23549c0bbf20b3241c798a66f6029ff5ac760 100644 (file)
@@ -2,9 +2,9 @@
 
 struct A
 {
-  int i;
-  A() i() {}  // { dg-error "expected" }
-}; // { dg-error "expected" }
+  int i; // { dg-error "conflicts" }
+  A() i() {}  // { dg-error "declaration" }
+};
 
 struct B
 {
diff --git a/gcc/testsuite/g++.dg/parse/semicolon2.C b/gcc/testsuite/g++.dg/parse/semicolon2.C
new file mode 100644 (file)
index 0000000..d14a225
--- /dev/null
@@ -0,0 +1,9 @@
+// PR c++/45332
+// { dg-do compile }
+
+class C
+{
+ int x                         // { dg-error "at end of member declaration" }
+
+ const int foo() { return x; }
+};