On 2014-03-27 21:16, Adam Butcher wrote:
On 2014-03-27 20:45, Adam Butcher wrote:
PR c++/60573
* name-lookup.h (cp_binding_level): New field scope_defines_class_p.
* semantics.c (begin_class_definition): Set scope_defines_class_p.
* pt.c (instantiate_class_template_1): Likewise.
* parser.c (synthesize_implicit_template_parm): Use cp_binding_level:: scope_defines_class_p rather than TYPE_BEING_DEFINED as the predicate
for unwinding to class-defining scope to handle the erroneous
definition of a generic function of an arbitrarily nested class within an
enclosing class.

Still got issues with this.  It fails on out-of-line defs.  I'll have
another look.

Turns out the solution was OK but I didn't account for the class-defining scope being reused for subsequent out-of-line declarations. I've made 'scope_defines_class_p' in to the now transient 'defining_class_p' predicate which is reset on leaving scope. I've ditched the 'scope_' prefix and also ditched the modifications to 'instantiate_class_template_1'.

The patch delta is included below (but will probably be munged by my webmail client). I'll reply to this with the full patch.

There is also the fix for PR c++/60626 (http://gcc.gnu.org/ml/gcc-patches/2014-03/msg01294.html) that deals with another form of erroneous generic function declarations with nested class scope.

Cheers,
Adam


diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 53f14f3..0137c3f 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -1630,10 +1630,14 @@ leave_scope (void)
       free_binding_level = scope;
     }

-  /* Find the innermost enclosing class scope, and reset
-     CLASS_BINDING_LEVEL appropriately.  */
   if (scope->kind == sk_class)
     {
+      /* Reset DEFINING_CLASS_P to allow for reuse of a
+        class-defining scope in a non-defining context.  */
+      scope->defining_class_p = 0;
+
+      /* Find the innermost enclosing class scope, and reset
+        CLASS_BINDING_LEVEL appropriately.  */
       class_binding_level = NULL;
for (scope = current_binding_level; scope; scope = scope->level_chain)
        if (scope->kind == sk_class)
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 9e5d812..40e0338 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -255,9 +255,12 @@ struct GTY(()) cp_binding_level {
   unsigned more_cleanups_ok : 1;
   unsigned have_cleanups : 1;

-  /* Set if this scope is of sk_class kind and is the defining
-     scope for this_entity.  */
-  unsigned scope_defines_class_p : 1;
+  /* Transient state set if this scope is of sk_class kind
+     and is in the process of defining 'this_entity'.  Reset
+     on leaving the class definition to allow for the scope
+     to be subsequently re-used as a non-defining scope for
+     'this_entity'.  */
+  unsigned defining_class_p : 1;

   /* 23 bits left to fill a 32-bit word.  */
 };
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4919a67..0945bfd 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -32027,7 +32027,7 @@ synthesize_implicit_template_parm (cp_parser *parser) declarator should be injected into the scope of 'A' as if the
            ill-formed template was specified explicitly.  */

- while (scope->kind == sk_class && !scope->scope_defines_class_p)
+         while (scope->kind == sk_class && !scope->defining_class_p)
            {
              parent_scope = scope;
              scope = scope->level_chain;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 90faeec..c791d03 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8905,12 +8905,9 @@ instantiate_class_template_1 (tree type)
     return type;

   /* Now we're really doing the instantiation.  Mark the type as in
-     the process of being defined...  */
+     the process of being defined.  */
   TYPE_BEING_DEFINED (type) = 1;

-  /* ... and the scope defining it.  */
-  class_binding_level->scope_defines_class_p = 1;
-
   /* We may be in the middle of deferred access check.  Disable
      it now.  */
   push_deferring_access_checks (dk_no_deferred);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index deba2ab..207a42d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2777,7 +2777,7 @@ begin_class_definition (tree t)
   maybe_process_partial_specialization (t);
   pushclass (t);
   TYPE_BEING_DEFINED (t) = 1;
-  class_binding_level->scope_defines_class_p = 1;
+  class_binding_level->defining_class_p = 1;

   if (flag_pack_struct)
     {

Reply via email to