re PR c++/15786 (Bad error message for frequently occuring error.)
authorMark Mitchell <mark@codesourcery.com>
Tue, 12 Oct 2004 01:52:19 +0000 (01:52 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 12 Oct 2004 01:52:19 +0000 (01:52 +0000)
PR c++/15786
* parser.c (cp_parser_declarator): Add member_p parameter.
(cp_parser_condition): Adjust calls to cp_parser_declarator.
(cp_parser_explicit_instantiation): Likewise.
(cp_parser_init_declarator): Likewise.
(cp_parser_direct_declarator): Add member_p parameter.  Do not
parse tentatively when parsing the parameters to a member.
(cp_parser_type_id): Adjust calls to cp_parser_declarator.
(cp_parser_parameter_declaration): Likewise.
(cp_parser_member_declaration): Likewise.
(cp_parser_exception_declaration): Likewise.

PR c++/15876
* g++.dg/parse/error22.C: New test.

From-SVN: r88914

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/error22.C [new file with mode: 0644]

index 44c6b70..a9bcec9 100644 (file)
@@ -1,5 +1,17 @@
 2004-10-11  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/15786
+       * parser.c (cp_parser_declarator): Add member_p parameter. 
+       (cp_parser_condition): Adjust calls to cp_parser_declarator.
+       (cp_parser_explicit_instantiation): Likewise.
+       (cp_parser_init_declarator): Likewise.
+       (cp_parser_direct_declarator): Add member_p parameter.  Do not
+       parse tentatively when parsing the parameters to a member.
+       (cp_parser_type_id): Adjust calls to cp_parser_declarator.
+       (cp_parser_parameter_declaration): Likewise.
+       (cp_parser_member_declaration): Likewise.
+       (cp_parser_exception_declaration): Likewise.
+
        PR c++/17936
        * cp-tree.h (CLASSTYPE_TEMPLATE_SPECIALIZATION): Add a comment.
        * pt.c (optimize_specialization_lookup_p): Do not optimize lookups
index 7fb9d96..d914ed2 100644 (file)
@@ -1543,9 +1543,9 @@ static void cp_parser_linkage_specification
 static tree cp_parser_init_declarator
   (cp_parser *, cp_decl_specifier_seq *, bool, bool, int, bool *);
 static cp_declarator *cp_parser_declarator
-  (cp_parser *, cp_parser_declarator_kind, int *, bool *);
+  (cp_parser *, cp_parser_declarator_kind, int *, bool *, bool);
 static cp_declarator *cp_parser_direct_declarator
-  (cp_parser *, cp_parser_declarator_kind, int *);
+  (cp_parser *, cp_parser_declarator_kind, int *, bool);
 static enum tree_code cp_parser_ptr_operator
   (cp_parser *, tree *, cp_cv_quals *);
 static cp_cv_quals cp_parser_cv_qualifier_seq_opt
@@ -6275,7 +6275,8 @@ cp_parser_condition (cp_parser* parser)
       /* Parse the declarator.  */
       declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                                         /*ctor_dtor_or_conv_p=*/NULL,
-                                        /*parenthesized_p=*/NULL);
+                                        /*parenthesized_p=*/NULL,
+                                        /*member_p=*/false);
       /* Parse the attributes.  */
       attributes = cp_parser_attributes_opt (parser);
       /* Parse the asm-specification.  */
@@ -9072,7 +9073,8 @@ cp_parser_explicit_instantiation (cp_parser* parser)
       declarator
        = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                                /*ctor_dtor_or_conv_p=*/NULL,
-                               /*parenthesized_p=*/NULL);
+                               /*parenthesized_p=*/NULL,
+                               /*member_p=*/false);
       cp_parser_check_for_definition_in_return_type (declarator,
                                                     declares_class_or_enum);
       if (declarator != cp_error_declarator)
@@ -10489,7 +10491,8 @@ cp_parser_init_declarator (cp_parser* parser,
   declarator
     = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                            &ctor_dtor_or_conv_p,
-                           /*parenthesized_p=*/NULL);
+                           /*parenthesized_p=*/NULL,
+                           /*member_p=*/false);
   /* Gather up the deferred checks.  */
   stop_deferring_access_checks ();
 
@@ -10749,13 +10752,16 @@ cp_parser_init_declarator (cp_parser* parser,
    expression, not a declaration.)
 
    If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
-   the declarator is a direct-declarator of the form "(...)".  */
+   the declarator is a direct-declarator of the form "(...)".  
+
+   MEMBER_P is true iff this declarator is a member-declarator.  */
 
 static cp_declarator *
 cp_parser_declarator (cp_parser* parser,
                       cp_parser_declarator_kind dcl_kind,
                       int* ctor_dtor_or_conv_p,
-                     bool* parenthesized_p)
+                     bool* parenthesized_p,
+                     bool member_p)
 {
   cp_token *token;
   cp_declarator *declarator;
@@ -10796,7 +10802,8 @@ cp_parser_declarator (cp_parser* parser,
       /* Parse the dependent declarator.  */
       declarator = cp_parser_declarator (parser, dcl_kind,
                                         /*ctor_dtor_or_conv_p=*/NULL,
-                                        /*parenthesized_p=*/NULL);
+                                        /*parenthesized_p=*/NULL,
+                                        /*member_p=*/false);
 
       /* If we are parsing an abstract-declarator, we must handle the
         case where the dependent declarator is absent.  */
@@ -10821,7 +10828,8 @@ cp_parser_declarator (cp_parser* parser,
        *parenthesized_p = cp_lexer_next_token_is (parser->lexer,
                                                   CPP_OPEN_PAREN);
       declarator = cp_parser_direct_declarator (parser, dcl_kind,
-                                               ctor_dtor_or_conv_p);
+                                               ctor_dtor_or_conv_p,
+                                               member_p);
     }
 
   if (attributes && declarator != cp_error_declarator)
@@ -10854,13 +10862,14 @@ cp_parser_declarator (cp_parser* parser,
    we are parsing a direct-declarator.  It is
    CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
    of ambiguity we prefer an abstract declarator, as per
-   [dcl.ambig.res].  CTOR_DTOR_OR_CONV_P is as for
+   [dcl.ambig.res].  CTOR_DTOR_OR_CONV_P and MEMBER_P are as for
    cp_parser_declarator.  */
 
 static cp_declarator *
 cp_parser_direct_declarator (cp_parser* parser,
                              cp_parser_declarator_kind dcl_kind,
-                             int* ctor_dtor_or_conv_p)
+                             int* ctor_dtor_or_conv_p,
+                            bool member_p)
 {
   cp_token *token;
   cp_declarator *declarator = NULL;
@@ -10919,7 +10928,14 @@ cp_parser_direct_declarator (cp_parser* parser,
              cp_parameter_declarator *params;
              unsigned saved_num_template_parameter_lists;
 
-             cp_parser_parse_tentatively (parser);
+             /* In a member-declarator, the only valid interpretation
+                of a parenthesis is the start of a
+                parameter-declaration-clause.  (It is invalid to
+                initialize a static data member with a parenthesized
+                initializer; only the "=" form of initialization is
+                permitted.)  */
+             if (!member_p)
+               cp_parser_parse_tentatively (parser);
 
              /* Consume the `('.  */
              cp_lexer_consume_token (parser->lexer);
@@ -10945,7 +10961,7 @@ cp_parser_direct_declarator (cp_parser* parser,
 
              /* If all went well, parse the cv-qualifier-seq and the
                 exception-specification.  */
-             if (cp_parser_parse_definitely (parser))
+             if (member_p || cp_parser_parse_definitely (parser))
                {
                  cp_cv_quals cv_quals;
                  tree exception_specification;
@@ -10993,7 +11009,8 @@ cp_parser_direct_declarator (cp_parser* parser,
              parser->in_type_id_in_expr_p = true;
              declarator
                = cp_parser_declarator (parser, dcl_kind, ctor_dtor_or_conv_p,
-                                       /*parenthesized_p=*/NULL);
+                                       /*parenthesized_p=*/NULL,
+                                       member_p);
              parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
              first = false;
              /* Expect a `)'.  */
@@ -11420,7 +11437,8 @@ cp_parser_type_id (cp_parser* parser)
   /* Look for the declarator.  */
   abstract_declarator
     = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT, NULL,
-                           /*parenthesized_p=*/NULL);
+                           /*parenthesized_p=*/NULL,
+                           /*member_p=*/false);
   /* Check to see if there really was a declarator.  */
   if (!cp_parser_parse_definitely (parser))
     abstract_declarator = NULL;
@@ -11774,7 +11792,8 @@ cp_parser_parameter_declaration (cp_parser *parser,
       declarator = cp_parser_declarator (parser,
                                         CP_PARSER_DECLARATOR_EITHER,
                                         /*ctor_dtor_or_conv_p=*/NULL,
-                                        parenthesized_p);
+                                        parenthesized_p,
+                                        /*member_p=*/false);
       parser->default_arg_ok_p = saved_default_arg_ok_p;
       /* After the declarator, allow more attributes.  */
       decl_specifiers.attributes
@@ -13090,7 +13109,8 @@ cp_parser_member_declaration (cp_parser* parser)
              declarator
                = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
                                        &ctor_dtor_or_conv_p,
-                                       /*parenthesized_p=*/NULL);
+                                       /*parenthesized_p=*/NULL,
+                                       /*member_p=*/true);
 
              /* If something went wrong parsing the declarator, make sure
                 that we at least consume some tokens.  */
@@ -13707,7 +13727,8 @@ cp_parser_exception_declaration (cp_parser* parser)
   else
     declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
                                       /*ctor_dtor_or_conv_p=*/NULL,
-                                      /*parenthesized_p=*/NULL);
+                                      /*parenthesized_p=*/NULL,
+                                      /*member_p=*/false);
 
   /* Restore the saved message.  */
   parser->type_definition_forbidden_message = saved_message;
index ac5fa07..13217f7 100644 (file)
@@ -1,5 +1,8 @@
 2004-10-11  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/15876
+       * g++.dg/parse/error22.C: New test.
+
        PR c++/17936
        * g++.dg/template/spec18.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/parse/error22.C b/gcc/testsuite/g++.dg/parse/error22.C
new file mode 100644 (file)
index 0000000..da3a62f
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/15786
+
+struct A {
+  void foo(bar* p); /* { dg-error "declared" } */
+};