OSDN Git Service

PR c++/19253
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Nov 2005 21:34:51 +0000 (21:34 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Nov 2005 21:34:51 +0000 (21:34 +0000)
* parser.c (cp_parser_postfix_expression): Use
cp_parser_elaborated_type_specifier to handle typename-types in
functional casts.
(cp_parser_enclosed_argument_list): Skip ahead to the end of the
template argument list if the closing ">" is not found.
PR c++/19253
* g++.dg/parse/typename8.C: Compile with -w -fpermissive.
* g++.dg/parse/typename9.C: New test.
* g++/dg/parse/typename10.C: Likewise.

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

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

index 410c88f..3df7901 100644 (file)
@@ -1,5 +1,12 @@
 2005-11-02  Mark Mitchell  <mark@codesourcery.com>
 
 2005-11-02  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/19253
+       * parser.c (cp_parser_postfix_expression): Use
+       cp_parser_elaborated_type_specifier to handle typename-types in
+       functional casts.
+       (cp_parser_enclosed_argument_list): Skip ahead to the end of the
+       template argument list if the closing ">" is not found.
+
        PR c++/24569
        * pt.c (instantiate_decl): Use cp_finish_decl, not
        finish_static_data_member_decl. 
        PR c++/24569
        * pt.c (instantiate_decl): Use cp_finish_decl, not
        finish_static_data_member_decl. 
index a065c25..94ce45f 100644 (file)
@@ -3961,55 +3961,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
 
     case RID_TYPENAME:
       {
 
     case RID_TYPENAME:
       {
-       bool template_p = false;
-       tree id;
        tree type;
        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.  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
-          identifier.  */
-       cp_parser_parse_tentatively (parser);
-       /* Try a template-id.  */
-       id = cp_parser_template_id (parser, template_p,
-                                   /*check_dependency_p=*/true,
-                                   /*is_declaration=*/true);
-       /* 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 || 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
-           && (!TYPE_P (scope)
-               || !dependent_type_p (parser->scope)))
-         type = TREE_TYPE (id);
-       /* Create a TYPENAME_TYPE to represent the type to which the
-          functional cast is being performed.  */
-       else
-         type = make_typename_type (parser->scope, id,
-                                    typename_type,
-                                    /*complain=*/1);
-
+       /* The syntax permitted here is the same permitted for an
+          elaborated-type-specifier.  */
+       type = cp_parser_elaborated_type_specifier (parser,
+                                                   /*is_friend=*/false,
+                                                   /*is_declaration=*/false);
        postfix_expression = cp_parser_functional_cast (parser, type);
       }
       break;
        postfix_expression = cp_parser_functional_cast (parser, type);
       }
       break;
@@ -15498,11 +15455,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
                 "a template argument list");
        }
     }
                 "a template argument list");
        }
     }
-  else if (!cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
-    error ("missing %<>%> to terminate the template argument list");
   else
   else
-    /* It's what we want, a '>'; consume it.  */
-    cp_lexer_consume_token (parser->lexer);
+    cp_parser_skip_until_found (parser, CPP_GREATER, "`>'");
   /* The `>' token might be a greater-than operator again now.  */
   parser->greater_than_is_operator_p
     = saved_greater_than_is_operator_p;
   /* The `>' token might be a greater-than operator again now.  */
   parser->greater_than_is_operator_p
     = saved_greater_than_is_operator_p;
index 0b9bd92..aa01d33 100644 (file)
@@ -1,3 +1,10 @@
+2005-11-02  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c++/19253
+       * g++.dg/parse/typename8.C: Compile with -w -fpermissive.
+       * g++.dg/parse/typename9.C: New test.
+       * g++/dg/parse/typename10.C: Likewise.
+
 2005-11-02  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR fortran/18157
 2005-11-02  Andrew Pinski  <pinskia@physics.uc.edu>
 
        PR fortran/18157
diff --git a/gcc/testsuite/g++.dg/parse/typename10.C b/gcc/testsuite/g++.dg/parse/typename10.C
new file mode 100644 (file)
index 0000000..64d6ae8
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/19253
+
+namespace N { struct X; }
+
+template<typename> struct A
+{
+  A<typename N::X x> a; // { dg-error "invalid" }
+};
index 413e954..e8e7627 100644 (file)
@@ -4,6 +4,8 @@
 // PR 23797:ICE
 // Origin:  Volker Reichelt <reichelt@gcc.gnu.org>
 
 // PR 23797:ICE
 // Origin:  Volker Reichelt <reichelt@gcc.gnu.org>
 
+// { dg-options "-fpermissive -w" }
+
 struct A { typedef int X; };
 
 int i = typename A::X();
 struct A { typedef int X; };
 
 int i = typename A::X();
diff --git a/gcc/testsuite/g++.dg/parse/typename9.C b/gcc/testsuite/g++.dg/parse/typename9.C
new file mode 100644 (file)
index 0000000..aa72cd6
--- /dev/null
@@ -0,0 +1,3 @@
+struct A { typedef int X; };
+
+int i = typename A::X(); // { dg-error "typename" }