[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