re PR c++/5607 (No pointer adjustment in covariant return types)
authorJason Merrill <jason@redhat.com>
Thu, 25 Apr 2002 18:04:50 +0000 (14:04 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 25 Apr 2002 18:04:50 +0000 (14:04 -0400)
        PR c++/5607
        * search.c (check_final_overrider): No longer static.
        * class.c (update_vtable_entry_for_fn): Call it.
        * cp-tree.h: Adjust.

From-SVN: r52760

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/search.c
gcc/testsuite/g++.dg/inherit/covariant1.C [new file with mode: 0644]

index ee39ddc544268040f6e60db49ae50d13fb7f7dfe..22d45277ea31bc5d4bcfe970bf486fd2211c552c 100644 (file)
@@ -1,3 +1,10 @@
+2002-04-25  Jason Merrill  <jason@redhat.com>
+
+       PR c++/5607
+       * search.c (check_final_overrider): No longer static.
+       * class.c (update_vtable_entry_for_fn): Call it.
+       * cp-tree.h: Adjust.
+
 2002-04-25  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * cp-lang.c (LANG_HOOKS_SET_YYDEBUG): Remove.
index c8627fb36fd9eb4d233c63849f117396a2cad6f2..92f43298bdb1a8d6749631b28661ca516f806fb7 100644 (file)
@@ -2555,6 +2555,10 @@ update_vtable_entry_for_fn (t, binfo, fn, virtuals)
   if (overrider == error_mark_node)
     return;
 
+  /* Check for unsupported covariant returns again now that we've
+     calculated the base offsets.  */
+  check_final_overrider (TREE_PURPOSE (overrider), fn);
+
   /* Assume that we will produce a thunk that convert all the way to
      the final overrider, and not to an intermediate virtual base.  */
   virtual_base = NULL_TREE;
index 43b17c88cb332087881733b743508748ff029e47..8be1e6f4e0570aee2b81f4c18dc1e442d21e60ad 100644 (file)
@@ -4098,6 +4098,7 @@ extern tree lookup_conversions                    PARAMS ((tree));
 extern tree binfo_for_vtable                   PARAMS ((tree));
 extern tree binfo_from_vbase                   PARAMS ((tree));
 extern tree look_for_overrides_here            PARAMS ((tree, tree));
+extern int check_final_overrider               PARAMS ((tree, tree));
 extern tree dfs_walk                            PARAMS ((tree,
                                                       tree (*) (tree, void *),
                                                       tree (*) (tree, void *),
index 779b37a6e331a9531e984397f712df3826125ad3..38841589dfd257bc503fa05e7b7c9fe164b0eb01 100644 (file)
@@ -100,7 +100,6 @@ static tree dfs_push_decls PARAMS ((tree, void *));
 static tree dfs_unuse_fields PARAMS ((tree, void *));
 static tree add_conversions PARAMS ((tree, void *));
 static int covariant_return_p PARAMS ((tree, tree));
-static int check_final_overrider PARAMS ((tree, tree));
 static int look_for_overrides_r PARAMS ((tree, tree));
 static struct search_level *push_search_level
        PARAMS ((struct stack_level *, struct obstack *));
@@ -1798,7 +1797,7 @@ covariant_return_p (brettype, drettype)
 /* Check that virtual overrider OVERRIDER is acceptable for base function
    BASEFN. Issue diagnostic, and return zero, if unacceptable.  */
 
-static int
+int
 check_final_overrider (overrider, basefn)
      tree overrider, basefn;
 {
diff --git a/gcc/testsuite/g++.dg/inherit/covariant1.C b/gcc/testsuite/g++.dg/inherit/covariant1.C
new file mode 100644 (file)
index 0000000..516047e
--- /dev/null
@@ -0,0 +1,39 @@
+// PR c++/5607
+
+// Currently we don't support covariant returns that would actually require
+// a pointer adjustment.  We were failing to recognize this as such a case,
+// so were silently generating bad code.  When we do support covariant
+// returns properly, the expected error should go away, and the testcase
+// should pass execution.
+
+// { NOT YET dg-do run }
+
+class A {
+public:
+  virtual A* getThis() { return this; }
+};
+
+class B {
+int a;
+public:
+  virtual B* getThis() { return this; }
+};
+
+class AB : public A, public B {        // { dg-error "covariant" }
+public:
+  virtual AB* getThis() { return this; }
+};
+
+int main ()
+{
+  AB* ab = new AB();
+  
+  A* a = ab;
+  B* b = ab;
+
+  if (a->getThis() != a
+      || b->getThis() != b)
+    return 1;
+
+  return 0;
+}