OSDN Git Service

gcc/cp/
authorfroydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 6 Nov 2010 18:41:57 +0000 (18:41 +0000)
committerfroydnj <froydnj@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 6 Nov 2010 18:41:57 +0000 (18:41 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166406 138bc75d-0d04-0410-961f-82ee72b054a4

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 bfa4af4..784f3aa 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 6302864..6a9e4d7 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 4577eb2..911ba14 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 3df2483..0661136 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 3563c48..2ced6e3 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 8194585..3ea2354 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; }
+};