[PATCH] Fix PR c++/60573

Adam Butcher adam@jessamine.co.uk
Wed Mar 19 03:39:00 GMT 2014


	PR c++/60573
	* parser.c (synthesize_implicit_template_parm): Handle the fact that
	nested class member declarations erroneously appearing in an enclosing
	class contain an addition scope level for the class being defined.

	PR c++/60573
	* g++.dg/cpp1y/pr60573.C: New testcase.
---
 gcc/cp/parser.c                      | 18 ++++++++++++++++--
 gcc/testsuite/g++.dg/cpp1y/pr60573.C | 13 +++++++++++++
 2 files changed, 29 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/pr60573.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 46e2453..36872c9 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -32006,9 +32006,23 @@ synthesize_implicit_template_parm  (cp_parser *parser)
 	    must be injected in the scope of 'B', just beyond the scope of 'A'
 	    introduced by 'A::'.  */
 
-	  while (scope->kind == sk_class
-		 && !TYPE_BEING_DEFINED (scope->this_entity))
+	  while (scope->kind == sk_class)
 	    {
+	      /* In valid cases where the class being defined is reached, we're
+		 at the point where the template argument list should be
+		 injected for a generic member function.  In the erroneous case
+		 of generic member function of a nested class being declared in
+		 the enclosing class, an additional class scope for the
+		 enclosing class has been pushed by push_nested_class via
+		 push_scope in cp_parser_direct_declarator.  This additional
+		 scope needs to be skipped to reach the class definition scope
+		 where the template argument list should be injected.  */
+
+	      if (TYPE_BEING_DEFINED (scope->this_entity))
+		if (scope->level_chain == 0
+		    || scope->this_entity != scope->level_chain->this_entity)
+		  break;
+
 	      parent_scope = scope;
 	      scope = scope->level_chain;
 	    }
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60573.C b/gcc/testsuite/g++.dg/cpp1y/pr60573.C
new file mode 100644
index 0000000..7f56ff4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr60573.C
@@ -0,0 +1,13 @@
+// PR c++/60573
+// { dg-do compile { target c++1y } }
+// { dg-options "" }
+
+struct A
+{
+  struct B
+  {
+    void foo(auto);
+  };
+
+  void B::foo(auto) {}  // { dg-error "cannot define" }
+};
-- 
1.9.0



More information about the Gcc-patches mailing list