re PR c++/53563 (ICE in start_decl, at cp/decl.c:4427)
authorJason Merrill <jason@redhat.com>
Wed, 27 Jun 2012 19:19:09 +0000 (15:19 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 27 Jun 2012 19:19:09 +0000 (15:19 -0400)
PR c++/53563
* parser.c (cp_parser_template_id): Add tag_type parm.
(cp_parser_template_name): Likewise.
(cp_parser_id_expression, cp_parser_unqualified_id): Adjust.
(cp_parser_pseudo_destructor_name, cp_parser_type_name): Adjust.
(cp_parser_simple_type_specifier, cp_parser_class_name): Adjust.
(cp_parser_elaborated_type_specifier, cp_parser_class_head): Adjust.

From-SVN: r189024

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

index 4dbe915b73e0b44a1d04f4d035bd89eb7a32e59f..425bf7c7f23dafb9454f9955aa80ddafdf880c04 100644 (file)
@@ -1,3 +1,13 @@
+2012-06-27  Jason Merrill  <jason@redhat.com>
+
+       PR c++/53563
+       * parser.c (cp_parser_template_id): Add tag_type parm.
+       (cp_parser_template_name): Likewise.
+       (cp_parser_id_expression, cp_parser_unqualified_id): Adjust.
+       (cp_parser_pseudo_destructor_name, cp_parser_type_name): Adjust.
+       (cp_parser_simple_type_specifier, cp_parser_class_name): Adjust.
+       (cp_parser_elaborated_type_specifier, cp_parser_class_head): Adjust.
+
 2012-06-27  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
 
        PR C++/51033
index 46f1401b66fda5f8811eb94dc3e37140c393c3fc..7012caa2e6ae78637519aa22ede3c3810d17b745 100644 (file)
@@ -2062,9 +2062,9 @@ static tree cp_parser_template_parameter
 static tree cp_parser_type_parameter
   (cp_parser *, bool *);
 static tree cp_parser_template_id
-  (cp_parser *, bool, bool, bool);
+  (cp_parser *, bool, bool, enum tag_types, bool);
 static tree cp_parser_template_name
-  (cp_parser *, bool, bool, bool, bool *);
+  (cp_parser *, bool, bool, bool, enum tag_types, bool *);
 static tree cp_parser_template_argument_list
   (cp_parser *);
 static tree cp_parser_template_argument
@@ -4466,6 +4466,7 @@ cp_parser_id_expression (cp_parser *parser,
       id = cp_parser_template_id (parser,
                                  /*template_keyword_p=*/false,
                                  /*check_dependency_p=*/true,
+                                 none_type,
                                  declarator_p);
       /* If that worked, we're done.  */
       if (cp_parser_parse_definitely (parser))
@@ -4543,6 +4544,7 @@ cp_parser_unqualified_id (cp_parser* parser,
        /* Try a template-id.  */
        id = cp_parser_template_id (parser, template_keyword_p,
                                    check_dependency_p,
+                                   none_type,
                                    declarator_p);
        /* If it worked, we're done.  */
        if (cp_parser_parse_definitely (parser))
@@ -4554,6 +4556,7 @@ cp_parser_unqualified_id (cp_parser* parser,
     case CPP_TEMPLATE_ID:
       return cp_parser_template_id (parser, template_keyword_p,
                                    check_dependency_p,
+                                   none_type,
                                    declarator_p);
 
     case CPP_COMPL:
@@ -4769,6 +4772,7 @@ cp_parser_unqualified_id (cp_parser* parser,
          /* Try a template-id.  */
          id = cp_parser_template_id (parser, template_keyword_p,
                                      /*check_dependency_p=*/true,
+                                     none_type,
                                      declarator_p);
          /* If that worked, we're done.  */
          if (cp_parser_parse_definitely (parser))
@@ -6280,6 +6284,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
       cp_parser_template_id (parser,
                             /*template_keyword_p=*/true,
                             /*check_dependency_p=*/false,
+                            class_type,
                             /*is_declaration=*/true);
       /* Look for the `::' token.  */
       cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
@@ -12376,6 +12381,7 @@ static tree
 cp_parser_template_id (cp_parser *parser,
                       bool template_keyword_p,
                       bool check_dependency_p,
+                      enum tag_types tag_type,
                       bool is_declaration)
 {
   int i;
@@ -12432,6 +12438,7 @@ cp_parser_template_id (cp_parser *parser,
   templ = cp_parser_template_name (parser, template_keyword_p,
                                   check_dependency_p,
                                   is_declaration,
+                                  tag_type,
                                   &is_identifier);
   if (templ == error_mark_node || is_identifier)
     {
@@ -12604,6 +12611,7 @@ cp_parser_template_name (cp_parser* parser,
                         bool template_keyword_p,
                         bool check_dependency_p,
                         bool is_declaration,
+                        enum tag_types tag_type,
                         bool *is_identifier)
 {
   tree identifier;
@@ -12710,7 +12718,7 @@ cp_parser_template_name (cp_parser* parser,
 
   /* Look up the name.  */
   decl = cp_parser_lookup_name (parser, identifier,
-                               none_type,
+                               tag_type,
                                /*is_template=*/true,
                                /*is_namespace=*/false,
                                check_dependency_p,
@@ -13699,6 +13707,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
          type = cp_parser_template_id (parser,
                                        /*template_keyword_p=*/true,
                                        /*check_dependency_p=*/true,
+                                       none_type,
                                        /*is_declaration=*/false);
          /* If the template-id did not name a type, we are out of
             luck.  */
@@ -13811,6 +13820,7 @@ cp_parser_type_name (cp_parser* parser)
       type_decl = cp_parser_template_id (parser,
                                         /*template_keyword_p=*/false,
                                         /*check_dependency_p=*/false,
+                                        none_type,
                                         /*is_declaration=*/false);
       /* Note that this must be an instantiation of an alias template
         because [temp.names]/6 says:
@@ -14035,6 +14045,7 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
       token = cp_lexer_peek_token (parser->lexer);
       decl = cp_parser_template_id (parser, template_p,
                                    /*check_dependency_p=*/true,
+                                   tag_type,
                                    is_declaration);
       /* If we didn't find a template-id, look for an ordinary
         identifier.  */
@@ -17865,6 +17876,7 @@ cp_parser_class_name (cp_parser *parser,
       /* Try a template-id.  */
       decl = cp_parser_template_id (parser, template_keyword_p,
                                    check_dependency_p,
+                                   tag_type,
                                    is_declaration);
       if (decl == error_mark_node)
        return error_mark_node;
@@ -18317,7 +18329,7 @@ cp_parser_class_head (cp_parser* parser,
     = cp_parser_nested_name_specifier_opt (parser,
                                           /*typename_keyword_p=*/false,
                                           /*check_dependency_p=*/false,
-                                          /*type_p=*/false,
+                                          /*type_p=*/true,
                                           /*is_declaration=*/false);
   /* If there was a nested-name-specifier, then there *must* be an
      identifier.  */
@@ -18392,6 +18404,7 @@ cp_parser_class_head (cp_parser* parser,
       id = cp_parser_template_id (parser,
                                  /*template_keyword_p=*/false,
                                  /*check_dependency_p=*/true,
+                                 class_key,
                                  /*is_declaration=*/true);
       /* If that didn't work, it could still be an identifier.  */
       if (!cp_parser_parse_definitely (parser))
index 3f2a06fafe41076fe9780d1c16d2f7aa016a8fd3..ebba545cf3ab1417961c71f0865d4ae73af17dd4 100644 (file)
@@ -1,3 +1,9 @@
+2012-06-27  Jason Merrill  <jason@redhat.com>
+
+       PR c++/53563
+       * g++.dg/parse/template27.C: New.
+       * g++.dg/template/crash74.C: Adjust expected output.
+
 2012-06-27  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/41951
diff --git a/gcc/testsuite/g++.dg/parse/template27.C b/gcc/testsuite/g++.dg/parse/template27.C
new file mode 100644 (file)
index 0000000..8eee471
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/53563
+
+template<class T>
+struct s
+{
+ template<class U>
+ s(){}
+};
+
+int main() {
+ struct s<void>::s<int> a;     // { dg-error "no match" }
+}
index 9f2e415cfeeb25f9751e2f2e62c62c000a2f011c..d236947ec5116c341c48b9861bfbec10d7014bd0 100644 (file)
@@ -2,5 +2,5 @@
 // { dg-do compile }
 // { dg-options "" }
 
-template<typename F> void foo () { }
-template<typename F> struct foo<F> { };        // { dg-error "redeclared as" }
+template<typename F> void foo () { } // { dg-prune-output "previous" }
+template<typename F> struct foo<F> { };        // { dg-error "template" }