From a34824c092b6cf51fe19530d536301084ff57c77 Mon Sep 17 00:00:00 2001
From: mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 6 Dec 2006 05:12:46 +0000
Subject: [PATCH] 	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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119575 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/cp/ChangeLog                        |  6 ++++++
 gcc/cp/decl2.c                          |  9 ++-------
 gcc/cp/parser.c                         |  9 +++++++++
 gcc/testsuite/ChangeLog                 |  3 +++
 gcc/testsuite/g++.dg/template/crash63.C | 12 ++++++++++++
 5 files changed, 32 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/crash63.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d9de3612f743..9e63aca5e8a1 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 43889181f2f1..b2a97ff9dc2c 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 3ed749762429..82ee8873355a 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 d7bae48f0a10..089232fa404a 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 000000000000..b7056e8d85e7
--- /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;
+    }
+  };
+}
-- 
GitLab