class.c (dfs_find_final_overrider): Fix logic.
authorJason Merrill <jason@redhat.com>
Thu, 14 Jun 2001 12:59:40 +0000 (08:59 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 14 Jun 2001 12:59:40 +0000 (08:59 -0400)
        * class.c (dfs_find_final_overrider): Fix logic.

        * class.c (update_vtable_entry_for_fn): Uncomment optimization to use
        virtual thunk instead of non-virtual.
        (get_matching_virtual): Uncomment.

        * pt.c (unify): Don't recurse between the POINTER_TYPE and the
        OFFSET_TYPE.  If we're adding cv-quals, the extra ones would be on
        PARM, not ARG.

From-SVN: r43372

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/pt.c
gcc/testsuite/g++.old-deja/g++.other/override2.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/deduct7.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.pt/unify8.C

index f02f7fa..deaa83f 100644 (file)
@@ -1,3 +1,15 @@
+2001-06-14  Jason Merrill  <jason_merrill@redhat.com>
+
+       * class.c (dfs_find_final_overrider): Fix logic.
+
+       * class.c (update_vtable_entry_for_fn): Uncomment optimization to use
+       virtual thunk instead of non-virtual.
+       (get_matching_virtual): Uncomment.
+
+       * pt.c (unify): Don't recurse between the POINTER_TYPE and the
+       OFFSET_TYPE.  If we're adding cv-quals, the extra ones would be on
+       PARM, not ARG.
+
 2001-06-14  Nathan Sidwell  <nathan@codesourcery.com>
 
        * class.c (dfs_accumulate_vtbl_inits): For case 2 & 3, make sure
index 1fbf8d0..2ff9d14 100644 (file)
@@ -2567,32 +2567,44 @@ dfs_find_final_overrider (binfo, data)
              ffod->overriding_fn = method;
              ffod->overriding_base = TREE_VALUE (path);
            }
-         /* If we found the same overrider we already have, then
-            we just need to check that we're finding it in the same
-            place.  */
-         else if (ffod->overriding_fn == method)
+         else if (ffod->overriding_fn)
            {
-             if (ffod->overriding_base
-                 && (!tree_int_cst_equal 
+             /* We had a best overrider; let's see how this compares.  */
+
+             if (ffod->overriding_fn == method
+                 && (tree_int_cst_equal 
                      (BINFO_OFFSET (TREE_VALUE (path)),
                       BINFO_OFFSET (ffod->overriding_base))))
+               /* We found the same overrider we already have, and in the
+                  same place; it's still the best.  */;
+             else if (strictly_overrides (ffod->overriding_fn, method))
+               /* The old function overrides this function; it's still the
+                  best.  */;
+             else if (strictly_overrides (method, ffod->overriding_fn))
+               {
+                 /* The new function overrides the old; it's now the
+                    best.  */
+                 ffod->overriding_fn = method;
+                 ffod->overriding_base = TREE_VALUE (path);
+               }
+             else
                {
+                 /* Ambiguous.  */
                  ffod->candidates 
                    = build_tree_list (NULL_TREE,
                                       ffod->overriding_fn);
+                 if (method != ffod->overriding_fn)
+                   ffod->candidates 
+                     = tree_cons (NULL_TREE, method, ffod->candidates);
                  ffod->overriding_fn = NULL_TREE;
                  ffod->overriding_base = NULL_TREE;
                }
            }
-         /* If there was already an overrider, and it overrides this
-            function, then the old overrider is still the best
-            candidate.  */
-         else if (ffod->overriding_fn
-                  && strictly_overrides (ffod->overriding_fn,
-                                         method))
-           ;
          else
            {
+             /* We had a list of ambiguous overrides; let's see how this
+                new one compares.  */
+
              tree candidates;
              bool incomparable = false;
 
@@ -2692,7 +2704,6 @@ find_final_overrider (t, binfo, fn)
   return build_tree_list (ffod.overriding_fn, ffod.overriding_base);
 }
 
-#if 0
 /* Returns the function from the BINFO_VIRTUALS entry in T which matches
    the signature of FUNCTION_DECL FN, or NULL_TREE if none.  In other words,
    the function that the slot in T's primary vtable points to.  */
@@ -2709,7 +2720,6 @@ get_matching_virtual (t, fn)
       return BV_FN (f);
   return NULL_TREE;
 }
-#endif
 
 /* Update an entry in the vtable for BINFO, which is in the hierarchy
    dominated by T.  FN has been overriden in BINFO; VIRTUALS points to the
@@ -2784,10 +2794,6 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
       delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)),
                           BINFO_OFFSET (binfo));
 
-#if 0
-      /* Disable this optimization pending an ABI change, or until
-        we can force emission of the non-virtual thunk even if we don't
-        use it.  */
       if (! integer_zerop (delta))
        {
          /* We'll need a thunk.  But if we have a (perhaps formerly)
@@ -2810,7 +2816,6 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
                }
            }
        }
-#endif
     }
 
   modify_vtable_entry (t, 
index 1c9e659..d9fa17f 100644 (file)
@@ -8504,7 +8504,7 @@ unify (tparms, targs, parm, arg, strict)
     return 1;
 
   if (!(strict & UNIFY_ALLOW_OUTER_LEVEL)
-      && TYPE_P (arg) && !CP_TYPE_CONST_P (arg))
+      && TYPE_P (parm) && !CP_TYPE_CONST_P (parm))
     strict &= ~UNIFY_ALLOW_MORE_CV_QUAL;
   strict &= ~UNIFY_ALLOW_OUTER_LEVEL;
   strict &= ~UNIFY_ALLOW_DERIVED;
@@ -8712,6 +8712,18 @@ unify (tparms, targs, parm, arg, strict)
             level of pointers.  */
          strict |= (strict_in & UNIFY_ALLOW_DERIVED);
 
+       if (TREE_CODE (TREE_TYPE (parm)) == OFFSET_TYPE
+           && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE)
+         {
+           /* Avoid getting confused about cv-quals; don't recurse here.
+              Pointers to members should really be just OFFSET_TYPE, not
+              this two-level nonsense... */
+
+           parm = TREE_TYPE (parm);
+           arg = TREE_TYPE (arg);
+           goto offset;
+         }
+
        return unify (tparms, targs, TREE_TYPE (parm), 
                      TREE_TYPE (arg), strict);
       }
@@ -8864,6 +8876,7 @@ unify (tparms, targs, parm, arg, strict)
                                    DEDUCE_EXACT, 0, -1);
 
     case OFFSET_TYPE:
+    offset:
       if (TREE_CODE (arg) != OFFSET_TYPE)
        return 1;
       if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm),
diff --git a/gcc/testsuite/g++.old-deja/g++.other/override2.C b/gcc/testsuite/g++.old-deja/g++.other/override2.C
new file mode 100644 (file)
index 0000000..6466b7d
--- /dev/null
@@ -0,0 +1,9 @@
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Jason Merrill 14 Jun 2001 <jason@redhat.com>
+
+// Test for diagnosis of missing final overrider.
+
+struct A { virtual void f (); };
+struct B1: virtual A { virtual void f (); };
+struct B2: virtual A { virtual void f (); };
+struct C: public B1, public B2 {}; // ERROR - no final overrider
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/deduct7.C b/gcc/testsuite/g++.old-deja/g++.pt/deduct7.C
new file mode 100644 (file)
index 0000000..ec51d30
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Jason Merrill 14 Jun 2001 <jason@redhat.com>
+
+// Test that deduction can add cv-quals to a pointer-to-member type.
+
+struct A;
+int A::* pi;
+
+template <typename T> void f (const T A::*) {}
+
+int main ()
+{
+  f (pi);
+}
index 4e2f392..afe57d1 100644 (file)
@@ -9,10 +9,12 @@
 
 
 template <typename T> void Foo (T const **);
+template <typename T> void Bar (T const * const *);
 void Foo (int);       // ERROR - candidate
 void Foo (float);     // ERROR - candidate
 
 void baz (int **p1)
 {
   Foo (p1);   // ERROR - no such function
+  Bar (p1);   // OK
 }