aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-11-02 21:34:51 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-11-02 21:34:51 +0000
commit88a33c3406ca21d94db7ca092f3f65c898e23fda (patch)
treeb1be00dcdd39d0dc2ddc74914ba77a546db44ece /gcc
parenteca18fb4b61a16634e61b7cf281ab65ef3292a74 (diff)
downloadgcc-88a33c3406ca21d94db7ca092f3f65c898e23fda.zip
gcc-88a33c3406ca21d94db7ca092f3f65c898e23fda.tar.gz
gcc-88a33c3406ca21d94db7ca092f3f65c898e23fda.tar.bz2
re PR c++/19253 (bad error message / ICE for invalid template parameter)
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++/19253 * g++.dg/parse/typename8.C: Compile with -w -fpermissive. * g++.dg/parse/typename9.C: New test. * g++/dg/parse/typename10.C: Likewise. From-SVN: r106398
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/parser.c58
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/parse/typename10.C8
-rw-r--r--gcc/testsuite/g++.dg/parse/typename8.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/typename9.C3
6 files changed, 33 insertions, 52 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 410c88f..3df7901 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,12 @@
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.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index a065c25..94ce45f 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3961,55 +3961,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
case RID_TYPENAME:
{
- 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. 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;
@@ -15498,11 +15455,8 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser)
"a template argument list");
}
}
- else if (!cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
- error ("missing %<>%> to terminate the template argument list");
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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0b9bd92..aa01d33 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/parse/typename10.C b/gcc/testsuite/g++.dg/parse/typename10.C
new file mode 100644
index 0000000..64d6ae8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/typename10.C
@@ -0,0 +1,8 @@
+// PR c++/19253
+
+namespace N { struct X; }
+
+template<typename> struct A
+{
+ A<typename N::X x> a; // { dg-error "invalid" }
+};
diff --git a/gcc/testsuite/g++.dg/parse/typename8.C b/gcc/testsuite/g++.dg/parse/typename8.C
index 413e954..e8e7627 100644
--- a/gcc/testsuite/g++.dg/parse/typename8.C
+++ b/gcc/testsuite/g++.dg/parse/typename8.C
@@ -4,6 +4,8 @@
// PR 23797:ICE
// Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+// { dg-options "-fpermissive -w" }
+
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
index 0000000..aa72cd6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/typename9.C
@@ -0,0 +1,3 @@
+struct A { typedef int X; };
+
+int i = typename A::X(); // { dg-error "typename" }