re PR c++/49663 ([C++0x] ICE in lookup_base)
authorJason Merrill <jason@redhat.com>
Thu, 7 Jul 2011 21:53:58 +0000 (17:53 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 7 Jul 2011 21:53:58 +0000 (17:53 -0400)
PR c++/49663
* pt.c (push_deduction_access_scope): Preserve
processing_template_decl across push_to_top_level.
And revert:
* class.c (pushclass): Accept NULL argument.
(popclass): Deal with popping null class.
* pt.c (push_access_scope, pop_access_scope): Use them rather than
push_to_top_level/pop_from_top_level.
* name-lookup.c (lookup_name_real_1): Check current_class_type.

From-SVN: r176013

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/name-lookup.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/regress/regress4.C [new file with mode: 0644]

index c5c83d035ae8a527b3b89907e6a469ddffb76770..b926ec947a2e9c47023f2083af0245cc2f37ba15 100644 (file)
@@ -1,3 +1,15 @@
+2011-07-07  Jason Merrill  <jason@redhat.com>
+
+       PR c++/49663
+       * pt.c (push_deduction_access_scope): Preserve
+       processing_template_decl across push_to_top_level.
+       And revert:
+       * class.c (pushclass): Accept NULL argument.
+       (popclass): Deal with popping null class.
+       * pt.c (push_access_scope, pop_access_scope): Use them rather than
+       push_to_top_level/pop_from_top_level.
+       * name-lookup.c (lookup_name_real_1): Check current_class_type.
+
 2011-07-07  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/49644
index 6aefd6840756c5a7faf28e46f2e063b0f3b73fd4..7de104d4bc764ef23a56c63a806629311e6da714 100644 (file)
@@ -6125,9 +6125,6 @@ restore_class_cache (void)
    So that we may avoid calls to lookup_name, we cache the _TYPE
    nodes of local TYPE_DECLs in the TREE_TYPE field of the name.
 
-   For use by push_access_scope, we allow TYPE to be null to temporarily
-   push out of class scope.  This does not actually change binding levels.
-
    For multiple inheritance, we perform a two-pass depth-first search
    of the type lattice.  */
 
@@ -6136,6 +6133,8 @@ pushclass (tree type)
 {
   class_stack_node_t csn;
 
+  type = TYPE_MAIN_VARIANT (type);
+
   /* Make sure there is enough room for the new entry on the stack.  */
   if (current_class_depth + 1 >= current_class_stack_size)
     {
@@ -6154,15 +6153,6 @@ pushclass (tree type)
   csn->hidden = 0;
   current_class_depth++;
 
-  if (type == NULL_TREE)
-    {
-      current_class_name = current_class_type = NULL_TREE;
-      csn->hidden = true;
-      return;
-    }
-
-  type = TYPE_MAIN_VARIANT (type);
-
   /* Now set up the new type.  */
   current_class_name = TYPE_NAME (type);
   if (TREE_CODE (current_class_name) == TYPE_DECL)
@@ -6207,11 +6197,7 @@ invalidate_class_lookup_cache (void)
 void
 popclass (void)
 {
-  if (current_class_type)
-    poplevel_class ();
-  else
-    gcc_assert (current_class_depth
-               && current_class_stack[current_class_depth - 1].hidden);
+  poplevel_class ();
 
   current_class_depth--;
   current_class_name = current_class_stack[current_class_depth].name;
index 615e177e1f1b9e0abd467cf09036edc2e6efe4c7..06726da74ea8ea14a382f62b6b35949e6803a2be 100644 (file)
@@ -4473,7 +4473,7 @@ lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p,
   /* Conversion operators are handled specially because ordinary
      unqualified name lookup will not find template conversion
      operators.  */
-  if (IDENTIFIER_TYPENAME_P (name) && current_class_type)
+  if (IDENTIFIER_TYPENAME_P (name))
     {
       struct cp_binding_level *level;
 
index 17ca44cde0d0e32d826f222678feda6a25198d2c..2c64dd4a4c6aaeba1975d977f2cf9e0052288a2b 100644 (file)
@@ -214,7 +214,7 @@ push_access_scope (tree t)
   else if (DECL_CLASS_SCOPE_P (t))
     push_nested_class (DECL_CONTEXT (t));
   else
-    pushclass (NULL_TREE);
+    push_to_top_level ();
 
   if (TREE_CODE (t) == FUNCTION_DECL)
     {
@@ -239,7 +239,7 @@ pop_access_scope (tree t)
   if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
     pop_nested_class ();
   else
-    popclass ();
+    pop_from_top_level ();
 }
 
 /* Do any processing required when DECL (a member template
@@ -13843,7 +13843,13 @@ static void
 push_deduction_access_scope (tree tmpl)
 {
   if (cxx_dialect >= cxx0x)
-    push_access_scope (DECL_TEMPLATE_RESULT (tmpl));
+    {
+      int ptd = processing_template_decl;
+      push_access_scope (DECL_TEMPLATE_RESULT (tmpl));
+      /* Preserve processing_template_decl across push_to_top_level.  */
+      if (ptd && !processing_template_decl)
+       ++processing_template_decl;
+    }
   else
     push_deferring_access_checks (dk_no_check);
 }
index c57cb97105fb8c5f7feeabdd520edd0c09ccf466..6e17a559e24b0cd17bc91de673b4ba1ad6b15799 100644 (file)
@@ -1,3 +1,8 @@
+2011-07-06  Jason Merrill  <jason@redhat.com>
+
+       PR c++/49663
+       * g++.dg/cpp0x/regress/regress4.C: New.
+
 2011-07-07  Mikael Morin  <mikael.morin@sfr.fr>
 
        PR fortran/49648
diff --git a/gcc/testsuite/g++.dg/cpp0x/regress/regress4.C b/gcc/testsuite/g++.dg/cpp0x/regress/regress4.C
new file mode 100644 (file)
index 0000000..b56263a
--- /dev/null
@@ -0,0 +1,62 @@
+// PR c++/49663
+// { dg-options -std=c++0x }
+
+struct Nosm
+{
+    int m_R;
+};
+
+namespace dx {
+
+    struct onc
+    {
+        typedef void(*Cb)();
+
+        onc(Cb cb);
+    };
+
+    struct grac
+    {
+        template<class Derived> static void once();
+    };
+
+    template<class Derived>
+        struct tonc : onc
+        {
+            tonc() : onc(&grac::once<Derived>) {}
+
+            static Derived& get();
+        };
+
+    template<class Derived> void grac::once()
+    {
+        tonc<Derived>::get().h();
+    }
+}
+
+namespace
+{
+    template<typename T, int = sizeof(&T::m_R)>
+        struct has_R { };
+
+    template<typename T>
+        inline void
+        setR(T* m, has_R<T>* = 0)
+        { }
+
+    inline void setR(...) { }
+}
+
+template<typename M>
+    struct Qmi
+    : dx::tonc<Qmi<M> >
+    {
+        void h()
+        {
+            setR(&msg);
+        }
+
+        M msg;
+    };
+
+Qmi<Nosm> x;