re PR c++/20333 (ICE on invalid code, typename outside of a template)
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Sat, 19 Mar 2005 11:54:49 +0000 (11:54 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Sat, 19 Mar 2005 11:54:49 +0000 (11:54 +0000)
PR c++/20333
* parser.c (cp_parser_postfix_expression) <case RID_TYPENAME>:
Check the return value of cp_parser_nested_name_specifier.

* g++.dg/template/crash36.C: New test.

From-SVN: r96720

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

index 9bcdbb6..aade257 100644 (file)
@@ -1,3 +1,9 @@
+2005-03-19  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/20333
+       * parser.c (cp_parser_postfix_expression) <case RID_TYPENAME>:
+       Check the return value of cp_parser_nested_name_specifier.
+
 2005-03-18  Paolo Carlini  <pcarlini@suse.de>
 
        PR c++/20463
index 2724f5a..6df7bad 100644 (file)
@@ -3861,18 +3861,22 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
        bool template_p = false;
        tree id;
        tree type;
+       tree scope;
 
        /* Consume the `typename' token.  */
        cp_lexer_consume_token (parser->lexer);
        /* Look for the optional `::' operator.  */
        cp_parser_global_scope_opt (parser,
                                    /*current_scope_valid_p=*/false);
-       /* Look for the nested-name-specifier.  */
-       cp_parser_nested_name_specifier (parser,
-                                        /*typename_keyword_p=*/true,
-                                        /*check_dependency_p=*/true,
-                                        /*type_p=*/true,
-                                        /*is_declaration=*/true);
+       /* Look for the nested-name-specifier.  In case of error here,
+          consume the trailing id to avoid subsequent error messages
+          for usual cases.  */
+       scope = cp_parser_nested_name_specifier (parser,
+                                                /*typename_keyword_p=*/true,
+                                                /*check_dependency_p=*/true,
+                                                /*type_p=*/true,
+                                                /*is_declaration=*/true);
+
        /* Look for the optional `template' keyword.  */
        template_p = cp_parser_optional_template_keyword (parser);
        /* We don't know whether we're looking at a template-id or an
@@ -3885,9 +3889,13 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
        /* If that didn't work, try an identifier.  */
        if (!cp_parser_parse_definitely (parser))
          id = cp_parser_identifier (parser);
+
+       /* Don't process id if nested name specifier is invalid.  */
+       if (scope == error_mark_node)
+         return error_mark_node;
        /* If we look up a template-id in a non-dependent qualifying
           scope, there's no need to create a dependent type.  */
-       if (TREE_CODE (id) == TYPE_DECL
+       else if (TREE_CODE (id) == TYPE_DECL
            && !dependent_type_p (parser->scope))
          type = TREE_TYPE (id);
        /* Create a TYPENAME_TYPE to represent the type to which the
index 861304d..d223ddb 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-19  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/20333
+       * g++.dg/template/crash36.C: New test.
+
 2005-03-18  Paolo Carlini  <pcarlini@suse.de>
 
        PR c++/20463
diff --git a/gcc/testsuite/g++.dg/template/crash36.C b/gcc/testsuite/g++.dg/template/crash36.C
new file mode 100644 (file)
index 0000000..2f0ef92
--- /dev/null
@@ -0,0 +1,9 @@
+// { dg-do compile }
+
+// Origin: Ivan Godard <igodard@pacbell.net>
+//        Andrew Pinski <pinskia@gcc.gnu.org>
+
+// PR c++/20333: ICE parsing typename without nested-name-specifier
+
+template<class> struct f {};
+f<int> f2[2] = {typename f<int>()};    // { dg-error "" }