aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-11-03 02:48:44 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-11-03 02:48:44 +0000
commit71bd71860a61dbdbe2ff60a1a46a978baf0497ac (patch)
tree9b03eb1ecacc97313559f4f706dc4a6cdffcee9a
parent359202709b30a7b66b858591dfba5621caa0e5aa (diff)
downloadgcc-71bd71860a61dbdbe2ff60a1a46a978baf0497ac.zip
gcc-71bd71860a61dbdbe2ff60a1a46a978baf0497ac.tar.gz
gcc-71bd71860a61dbdbe2ff60a1a46a978baf0497ac.tar.bz2
re PR c++/18124 (ICE with invalid template template parameter)
PR c++/18124 * parser.c (cp_parser_type_parameter): Robustify. PR c++/18155 * parser.c (cp_parser_single_declaration): Disallow template typedefs. PR c++/18177 * typeck.c (build_const_cast): Use error_operand_p. PR c++/18124 * g++.dg/template/crash25.C: New test. PR c++/18155 * g++.dg/template/typedef2.C: New test. * g++.dg/parse/crash13.C: Adjust error markers. PR c++/18177 * g++.dg/conversion/const3.C: New test. From-SVN: r90016
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/parser.c34
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/testsuite/ChangeLog12
-rw-r--r--gcc/testsuite/g++.dg/conversion/const3.C7
-rw-r--r--gcc/testsuite/g++.dg/parse/crash13.C2
-rw-r--r--gcc/testsuite/g++.dg/template/crash25.C3
-rw-r--r--gcc/testsuite/g++.dg/template/typedef2.C3
8 files changed, 64 insertions, 11 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 61691e9..ef855e3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2004-11-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18124
+ * parser.c (cp_parser_type_parameter): Robustify.
+
+ PR c++/18155
+ * parser.c (cp_parser_single_declaration): Disallow template
+ typedefs.
+
+ PR c++/18177
+ * typeck.c (build_const_cast): Use error_operand_p.
+
2004-11-02 Ziemowit Laski <zlaski@apple.com>
* cp-lang.c (cxx_types_compatible_p): Remove prototype and definition.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e2afb3b..bea2f61 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8186,9 +8186,15 @@ cp_parser_type_parameter (cp_parser* parser)
if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
- identifier = cp_parser_identifier (parser);
+ {
+ identifier = cp_parser_identifier (parser);
+ /* Treat invalid names as if the parameter were nameless. */
+ if (identifier == error_mark_node)
+ identifier = NULL_TREE;
+ }
else
identifier = NULL_TREE;
+
/* Create the template parameter. */
parameter = finish_template_template_parm (class_type_node,
identifier);
@@ -8231,15 +8237,13 @@ cp_parser_type_parameter (cp_parser* parser)
/* Create the combined representation of the parameter and the
default argument. */
- parameter = build_tree_list (default_argument, parameter);
+ parameter = build_tree_list (default_argument, parameter);
}
break;
default:
- /* Anything else is an error. */
- cp_parser_error (parser,
- "expected %<class%>, %<typename%>, or %<template%>");
- parameter = error_mark_node;
+ gcc_unreachable ();
+ break;
}
return parameter;
@@ -14801,6 +14805,11 @@ cp_parser_single_declaration (cp_parser* parser,
cp_decl_specifier_seq decl_specifiers;
bool function_definition_p = false;
+ /* This function is only used when processing a template
+ declaration. */
+ gcc_assert (innermost_scope_kind () == sk_template_parms
+ || innermost_scope_kind () == sk_template_spec);
+
/* Defer access checks until we know what is being declared. */
push_deferring_access_checks (dk_deferred);
@@ -14812,6 +14821,14 @@ cp_parser_single_declaration (cp_parser* parser,
&declares_class_or_enum);
if (friend_p)
*friend_p = cp_parser_friend_p (&decl_specifiers);
+
+ /* There are no template typedefs. */
+ if (decl_specifiers.specs[(int) ds_typedef])
+ {
+ error ("template declaration of %qs", "typedef");
+ decl = error_mark_node;
+ }
+
/* Gather up the access checks that occurred the
decl-specifier-seq. */
stop_deferring_access_checks ();
@@ -14843,8 +14860,6 @@ cp_parser_single_declaration (cp_parser* parser,
decl = error_mark_node;
}
}
- else
- decl = NULL_TREE;
/* If it's not a template class, try for a template function. If
the next token is a `;', then this declaration does not declare
anything. But, if there were errors in the decl-specifiers, then
@@ -14869,7 +14884,8 @@ cp_parser_single_declaration (cp_parser* parser,
parser->object_scope = NULL_TREE;
/* Look for a trailing `;' after the declaration. */
if (!function_definition_p
- && !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))
+ && (decl == error_mark_node
+ || !cp_parser_require (parser, CPP_SEMICOLON, "`;'")))
cp_parser_skip_to_end_of_block_or_statement (parser);
return decl;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 3796ace..325dd56 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -5099,7 +5099,7 @@ build_const_cast_1 (tree dst_type, tree expr, bool complain,
tree
build_const_cast (tree type, tree expr)
{
- if (type == error_mark_node || expr == error_mark_node)
+ if (type == error_mark_node || error_operand_p (expr))
return error_mark_node;
if (processing_template_decl)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4ccbd09..68f830e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2004-11-02 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/18124
+ * g++.dg/template/crash25.C: New test.
+
+ PR c++/18155
+ * g++.dg/template/typedef2.C: New test.
+ * g++.dg/parse/crash13.C: Adjust error markers.
+
+ PR c++/18177
+ * g++.dg/conversion/const3.C: New test.
+
2004-11-03 Tobias Schlueter <tobias.schlueter@physik.uni-muenchen.de>
PR fortran/17535
diff --git a/gcc/testsuite/g++.dg/conversion/const3.C b/gcc/testsuite/g++.dg/conversion/const3.C
new file mode 100644
index 0000000..faa9f81
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/const3.C
@@ -0,0 +1,7 @@
+// PR c++/18177
+
+void foo()
+{
+ X; // { dg-error "" }
+ const_cast<int&>(X);
+}
diff --git a/gcc/testsuite/g++.dg/parse/crash13.C b/gcc/testsuite/g++.dg/parse/crash13.C
index d9e9087..3c298ec 100644
--- a/gcc/testsuite/g++.dg/parse/crash13.C
+++ b/gcc/testsuite/g++.dg/parse/crash13.C
@@ -13,7 +13,7 @@ struct A
template <typename T>
void func(A<T>::B* ) // { dg-error "variable|template|expression" }
-{ // { dg-error ";" }
+{
}
int main()
diff --git a/gcc/testsuite/g++.dg/template/crash25.C b/gcc/testsuite/g++.dg/template/crash25.C
new file mode 100644
index 0000000..fa77f0d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash25.C
@@ -0,0 +1,3 @@
+// PR c++/18124
+
+template <template <int> class class> class A {}; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/template/typedef2.C b/gcc/testsuite/g++.dg/template/typedef2.C
new file mode 100644
index 0000000..6c65671
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef2.C
@@ -0,0 +1,3 @@
+// PR c++/18155
+
+template<int> typedef struct A; // { dg-error "" }