]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/25439 ("template<> int A<0>" accepted)
authorMark Mitchell <mark@codesourcery.com>
Tue, 27 Dec 2005 09:05:17 +0000 (09:05 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 27 Dec 2005 09:05:17 +0000 (09:05 +0000)
PR c++/25439
* decl.c (grokdeclarator): Remove dead code.
* ptree.c (cxx_print_xnode): Handle BASELINK.
* parser.c (make_id_declarator): Add sfk parameter.
(cp_parser_direct_declarator): Do not pass TYPE_DECLs to
make_id_declarator.
(cp_parser_declarator_id): Simplify BASELINKs here.
(cp_parser_member_declaration): Adjust calls to
make_id_declarator.
PR c++/25439
* g++.dg/parse/crash17.C: Adjust error markers.
* g++.dg/template/error20.C: New test.

From-SVN: r109079

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/parser.c
gcc/cp/ptree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/crash17.C
gcc/testsuite/g++.dg/template/error20.C [new file with mode: 0644]

index 8f270641ffc8dfa8dab46543dd61d1fdec735da7..ae0fcf5a9a6a8d6b8612b873309db8019909c10b 100644 (file)
@@ -1,3 +1,15 @@
+2005-12-26  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/25439
+       * decl.c (grokdeclarator): Remove dead code.
+       * ptree.c (cxx_print_xnode): Handle BASELINK.
+       * parser.c (make_id_declarator): Add sfk parameter.  
+       (cp_parser_direct_declarator): Do not pass TYPE_DECLs to
+       make_id_declarator.
+       (cp_parser_declarator_id): Simplify BASELINKs here.
+       (cp_parser_member_declaration): Adjust calls to
+       make_id_declarator.
+
 2005-12-26  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/23171, c++/23172, c++/25417.
index 7517214bafa491281a697ca76d67efe14b7e3792..d6074d7edc965f29fb63751cf2cc6a812a77a991 100644 (file)
@@ -6725,10 +6725,6 @@ grokdeclarator (const cp_declarator *declarator,
                else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL)
                  in_namespace = qualifying_scope;
              }
-           if (TREE_CODE (decl) == BASELINK)
-             decl = BASELINK_FUNCTIONS (decl);
-           if (decl == error_mark_node)
-             return error_mark_node;
            switch (TREE_CODE (decl))
              {
              case BIT_NOT_EXPR:
@@ -6792,11 +6788,6 @@ grokdeclarator (const cp_declarator *declarator,
                  }
                break;
 
-             case TYPE_DECL:
-               dname = constructor_name (TREE_TYPE (decl));
-               name = IDENTIFIER_POINTER (dname);
-               break;
-
              default:
                gcc_unreachable ();
              }
@@ -7262,8 +7253,6 @@ grokdeclarator (const cp_declarator *declarator,
   else
     {
       unqualified_id = id_declarator->u.id.unqualified_name;
-      if (TREE_CODE (unqualified_id) == BASELINK)
-       unqualified_id = BASELINK_FUNCTIONS (unqualified_id);
       switch (TREE_CODE (unqualified_id))
        {
        case BIT_NOT_EXPR:
@@ -7271,11 +7260,6 @@ grokdeclarator (const cp_declarator *declarator,
            = constructor_name (TREE_OPERAND (unqualified_id, 0));
          break;
 
-       case TYPE_DECL:
-         unqualified_id
-           = constructor_name (TREE_TYPE (unqualified_id));
-         break;
-
        case IDENTIFIER_NODE:
        case TEMPLATE_ID_EXPR:
          break;
index ca561768ff09134491a1f6530c6e6c0dac8ef465..86d7edbcc47a3eee0a18131a4b30ee8733393e1a 100644 (file)
@@ -833,12 +833,15 @@ make_declarator (cp_declarator_kind kind)
   return declarator;
 }
 
-/* Make a declarator for a generalized identifier.  If non-NULL, the
-   identifier is QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is
-   just UNQUALIFIED_NAME.  */
+/* Make a declarator for a generalized identifier.  If
+   QUALIFYING_SCOPE is non-NULL, the identifier is
+   QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is just
+   UNQUALIFIED_NAME.  SFK indicates the kind of special function this
+   is, if any.   */
 
 static cp_declarator *
-make_id_declarator (tree qualifying_scope, tree unqualified_name)
+make_id_declarator (tree qualifying_scope, tree unqualified_name,
+                   special_function_kind sfk)
 {
   cp_declarator *declarator;
 
@@ -855,10 +858,14 @@ make_id_declarator (tree qualifying_scope, tree unqualified_name)
   if (qualifying_scope && TYPE_P (qualifying_scope))
     qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);
 
+  gcc_assert (TREE_CODE (unqualified_name) == IDENTIFIER_NODE
+             || TREE_CODE (unqualified_name) == BIT_NOT_EXPR
+             || TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR);
+
   declarator = make_declarator (cdk_id);
   declarator->u.id.qualifying_scope = qualifying_scope;
   declarator->u.id.unqualified_name = unqualified_name;
-  declarator->u.id.sfk = sfk_none;
+  declarator->u.id.sfk = sfk;
 
   return declarator;
 }
@@ -11354,6 +11361,7 @@ cp_parser_direct_declarator (cp_parser* parser,
        {
          tree qualifying_scope;
          tree unqualified_name;
+         special_function_kind sfk;
 
          /* Parse a declarator-id */
          if (dcl_kind == CP_PARSER_DECLARATOR_EITHER)
@@ -11411,9 +11419,7 @@ cp_parser_direct_declarator (cp_parser* parser,
              qualifying_scope = type;
            }
 
-         declarator = make_id_declarator (qualifying_scope,
-                                          unqualified_name);
-         declarator->id_loc = token->location;
+         sfk = sfk_none;
          if (unqualified_name)
            {
              tree class_type;
@@ -11424,28 +11430,9 @@ cp_parser_direct_declarator (cp_parser* parser,
              else
                class_type = current_class_type;
 
-             if (class_type)
+             if (TREE_CODE (unqualified_name) == TYPE_DECL)
                {
-                 if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
-                   declarator->u.id.sfk = sfk_destructor;
-                 else if (IDENTIFIER_TYPENAME_P (unqualified_name))
-                   declarator->u.id.sfk = sfk_conversion;
-                 else if (/* There's no way to declare a constructor
-                             for an anonymous type, even if the type
-                             got a name for linkage purposes.  */
-                          !TYPE_WAS_ANONYMOUS (class_type)
-                          && (constructor_name_p (unqualified_name,
-                                                  class_type)
-                              || (TREE_CODE (unqualified_name) == TYPE_DECL
-                                  && (same_type_p
-                                      (TREE_TYPE (unqualified_name),
-                                       class_type)))))
-                   declarator->u.id.sfk = sfk_constructor;
-
-                 if (ctor_dtor_or_conv_p && declarator->u.id.sfk != sfk_none)
-                   *ctor_dtor_or_conv_p = -1;
-                 if (qualifying_scope
-                     && TREE_CODE (unqualified_name) == TYPE_DECL
+                 if (qualifying_scope 
                      && CLASSTYPE_USE_TEMPLATE (TREE_TYPE (unqualified_name)))
                    {
                      error ("invalid use of constructor as a template");
@@ -11454,9 +11441,50 @@ cp_parser_direct_declarator (cp_parser* parser,
                              class_type,
                              DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
                              class_type, class_type);
+                     declarator = cp_error_declarator;
+                     break;
+                   }
+                 else if (class_type
+                          && same_type_p (TREE_TYPE (unqualified_name),
+                                          class_type))
+                   unqualified_name = constructor_name (class_type);
+                 else
+                   {
+                     /* We do not attempt to print the declarator
+                        here because we do not have enough
+                        information about its original syntactic
+                        form.  */
+                     error ("invalid declarator");
+                     declarator = cp_error_declarator;
+                     break;
                    }
                }
+
+             if (class_type)
+               {
+                 if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
+                   sfk = sfk_destructor;
+                 else if (IDENTIFIER_TYPENAME_P (unqualified_name))
+                   sfk = sfk_conversion;
+                 else if (/* There's no way to declare a constructor
+                             for an anonymous type, even if the type
+                             got a name for linkage purposes.  */
+                          !TYPE_WAS_ANONYMOUS (class_type)
+                          && constructor_name_p (unqualified_name,
+                                                 class_type))
+                   {
+                     unqualified_name = constructor_name (class_type);
+                     sfk = sfk_constructor;
+                   }
+
+                 if (ctor_dtor_or_conv_p && sfk != sfk_none)
+                   *ctor_dtor_or_conv_p = -1;
+               }
            }
+         declarator = make_id_declarator (qualifying_scope, 
+                                          unqualified_name,
+                                          sfk);
+         declarator->id_loc = token->location;
 
        handle_declarator:;
          scope = get_scope_of_declarator (declarator);
@@ -11666,6 +11694,7 @@ cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
 static tree
 cp_parser_declarator_id (cp_parser* parser)
 {
+  tree id;
   /* The expression must be an id-expression.  Assume that qualified
      names are the names of types so that:
 
@@ -11680,11 +11709,14 @@ cp_parser_declarator_id (cp_parser* parser)
        int S<T>::R<T>::i = 3;
 
      will work, too.  */
-  return cp_parser_id_expression (parser,
-                                 /*template_keyword_p=*/false,
-                                 /*check_dependency_p=*/false,
-                                 /*template_p=*/NULL,
-                                 /*declarator_p=*/true);
+  id = cp_parser_id_expression (parser,
+                               /*template_keyword_p=*/false,
+                               /*check_dependency_p=*/false,
+                               /*template_p=*/NULL,
+                               /*declarator_p=*/true);
+  if (BASELINK_P (id))
+    id = BASELINK_FUNCTIONS (id);
+  return id;
 }
 
 /* Parse a type-id.
@@ -13464,7 +13496,8 @@ cp_parser_member_declaration (cp_parser* parser)
              /* Create the bitfield declaration.  */
              decl = grokbitfield (identifier
                                   ? make_id_declarator (NULL_TREE,
-                                                        identifier)
+                                                        identifier,
+                                                        sfk_none)
                                   : NULL,
                                   &decl_specifiers,
                                   width);
@@ -17095,7 +17128,8 @@ cp_parser_objc_class_ivars (cp_parser* parser)
            {
              /* Get the name of the bitfield.  */
              declarator = make_id_declarator (NULL_TREE,
-                                              cp_parser_identifier (parser));
+                                              cp_parser_identifier (parser),
+                                              sfk_none);
 
             eat_colon:
              cp_lexer_consume_token (parser->lexer);  /* Eat ':'.  */
index 5d6651c53d81a2ba8fc0c1e644fc3b3a19e97704..c222bdcaecd82bac67690b043e5578f2a9c54315 100644 (file)
@@ -169,6 +169,12 @@ cxx_print_xnode (FILE *file, tree node, int indent)
 {
   switch (TREE_CODE (node))
     {
+    case BASELINK:
+      print_node (file, "functions", BASELINK_FUNCTIONS (node), indent + 4);
+      print_node (file, "binfo", BASELINK_BINFO (node), indent + 4);
+      print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node), 
+                 indent + 4);
+      break;
     case OVERLOAD:
       print_node (file, "function", OVL_FUNCTION (node), indent+4);
       print_node (file, "chain", TREE_CHAIN (node), indent+4);
index f8698658f6876e149e2fb9d8fb7e56cb0373e87a..91cb4e2803ce73ded57389061a71a6297c40ff61 100644 (file)
@@ -1,3 +1,9 @@
+2005-12-26  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/25439
+       * g++.dg/parse/crash17.C: Adjust error markers.
+       * g++.dg/template/error20.C: New test.
+
 2005-12-26  Mark Mitchell  <mark@codesourcery.com>
 
        PR c++/23172
index bdc66399f274ed08ba6d46bdf4c918f2430d9b92..e50f07af4a85da6857290e97c604a9fbd9c35ce4 100644 (file)
@@ -5,5 +5,5 @@ template <typename> class allocator;
 template<typename T> class vector { 
   // With the dg-error on the next line, we are really just trying to
   // check that the message is not an ICE message.
-  typedef typename allocator<T> allocator_type; // { dg-error "expected|forbids" }
+  typedef typename allocator<T> allocator_type; // { dg-error "expected|invalid" }
 }; 
diff --git a/gcc/testsuite/g++.dg/template/error20.C b/gcc/testsuite/g++.dg/template/error20.C
new file mode 100644 (file)
index 0000000..f81378f
--- /dev/null
@@ -0,0 +1,4 @@
+// PR c++/25439
+
+template<int> struct A;
+template<> int A<0>; // { dg-error "invalid" }