aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2006-12-06 05:12:46 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2006-12-06 05:12:46 +0000
commit7f1ba716a2b0eb2db5e641f739bf461912e7ef89 (patch)
tree8687d2f642a0080d050842e20ef8361d9010c77b
parentf75709c6f83fbf654b8bc283f27ddd8d4f894227 (diff)
downloadgcc-7f1ba716a2b0eb2db5e641f739bf461912e7ef89.zip
gcc-7f1ba716a2b0eb2db5e641f739bf461912e7ef89.tar.gz
gcc-7f1ba716a2b0eb2db5e641f739bf461912e7ef89.tar.bz2
re PR c++/29729 (ICE with template class in template function)
PR c++/29729 * decl2.c (check_member_template): Move check for member templates in local classes to ... * parser.c (cp_parser_template_declaration_after_export): ... here. PR c++/29729 * g++.dg/template/crash63.C: New test. From-SVN: r119575
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl2.c9
-rw-r--r--gcc/cp/parser.c9
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/template/crash63.C12
5 files changed, 32 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d9de361..9e63aca 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2006-12-05 Mark Mitchell <mark@codesourcery.com>
+ PR c++/29729
+ * decl2.c (check_member_template): Move check for member
+ templates in local classes to ...
+ * parser.c (cp_parser_template_declaration_after_export):
+ ... here.
+
PR c++/29728
* decl.c (check_array_designated_initializer): New function.
(maybe_deduce_size_from_array_init): Use it.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 4388918..b2a97ff 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -445,13 +445,8 @@ check_member_template (tree tmpl)
|| (TREE_CODE (decl) == TYPE_DECL
&& IS_AGGR_TYPE (TREE_TYPE (decl))))
{
- if (current_function_decl)
- /* 14.5.2.2 [temp.mem]
-
- A local class shall not have member templates. */
- error ("invalid declaration of member template %q#D in local class",
- decl);
-
+ /* The parser rejects template declarations in local classes. */
+ gcc_assert (!current_function_decl);
/* The parser rejects any use of virtual in a function template. */
gcc_assert (!(TREE_CODE (decl) == FUNCTION_DECL
&& DECL_VIRTUAL_P (decl)));
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 3ed7497..82ee887 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -15696,6 +15696,15 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
/* And the `<'. */
if (!cp_parser_require (parser, CPP_LESS, "`<'"))
return;
+ if (at_class_scope_p () && current_function_decl)
+ {
+ /* 14.5.2.2 [temp.mem]
+
+ A local class shall not have member templates. */
+ error ("invalid declaration of member template in local class");
+ cp_parser_skip_to_end_of_block_or_statement (parser);
+ return;
+ }
/* [temp]
A template ... shall not have C linkage. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d7bae48..089232f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2006-12-05 Mark Mitchell <mark@codesourcery.com>
+ PR c++/29729
+ * g++.dg/template/crash63.C: New test.
+
PR c++/29728
* g++.dg/template/crash62.C: New test.
diff --git a/gcc/testsuite/g++.dg/template/crash63.C b/gcc/testsuite/g++.dg/template/crash63.C
new file mode 100644
index 0000000..b7056e8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash63.C
@@ -0,0 +1,12 @@
+// PR c++/29729
+
+template<typename T> void foo(T)
+{
+ struct A
+ {
+ template<int> struct B // { dg-error "local class" }
+ {
+ typedef B<0> C;
+ }
+ };
+}