]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/60532 (r208573 causes Firefox build failure)
authorJason Merrill <jason@redhat.com>
Sat, 15 Mar 2014 01:39:03 +0000 (21:39 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 15 Mar 2014 01:39:03 +0000 (21:39 -0400)
PR c++/60532
PR c++/58678
* search.c (get_pure_virtuals): Handle abstract dtor here.
(dfs_get_pure_virtuals): Not here.

From-SVN: r208586

gcc/cp/ChangeLog
gcc/cp/search.c
gcc/testsuite/g++.dg/other/abstract6.C [new file with mode: 0644]

index b752ebe914f0d6b88753f0f04bb8f5270d22cd68..ca2f8c1270df253def537cf592f27a4931b07fcf 100644 (file)
@@ -1,5 +1,10 @@
 2014-03-14  Jason Merrill  <jason@redhat.com>
 
+       PR c++/60532
+       PR c++/58678
+       * search.c (get_pure_virtuals): Handle abstract dtor here.
+       (dfs_get_pure_virtuals): Not here.
+
        PR c++/58678
        * search.c (dfs_get_pure_virtuals): Treat the destructor of an
        abstract class as pure.
index 66c6df5215e74c26f34cc4e7a41e0aeadeaa3ced..d99e18215faf0c106f5c195a439623fa2d89da88 100644 (file)
@@ -2096,22 +2096,6 @@ dfs_get_pure_virtuals (tree binfo, void *data)
        if (DECL_PURE_VIRTUAL_P (BV_FN (virtuals)))
          vec_safe_push (CLASSTYPE_PURE_VIRTUALS (type), BV_FN (virtuals));
     }
-  /* Treat a virtual destructor in an abstract class as pure even if it
-     isn't declared as pure; there is no way it would be called through the
-     vtable except during construction, which causes undefined behavior.  */
-  if (binfo == TYPE_BINFO (type)
-      && CLASSTYPE_PURE_VIRTUALS (type)
-      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
-    {
-      tree dtor = CLASSTYPE_DESTRUCTORS (type);
-      if (DECL_VIRTUAL_P (dtor) && !DECL_PURE_VIRTUAL_P (dtor))
-       {
-         tree clone;
-         DECL_PURE_VIRTUAL_P (dtor) = true;
-         FOR_EACH_CLONE (clone, dtor)
-           DECL_PURE_VIRTUAL_P (clone) = true;
-       }
-    }
 
   return NULL_TREE;
 }
@@ -2131,6 +2115,22 @@ get_pure_virtuals (tree type)
      which it is a primary base will contain vtable entries for the
      pure virtuals in the base class.  */
   dfs_walk_once (TYPE_BINFO (type), NULL, dfs_get_pure_virtuals, type);
+
+  /* Treat a virtual destructor in an abstract class as pure even if it
+     isn't declared as pure; there is no way it would be called through the
+     vtable except during construction, which causes undefined behavior.  */
+  if (CLASSTYPE_PURE_VIRTUALS (type)
+      && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+    {
+      tree dtor = CLASSTYPE_DESTRUCTORS (type);
+      if (dtor && DECL_VIRTUAL_P (dtor) && !DECL_PURE_VIRTUAL_P (dtor))
+       {
+         tree clone;
+         DECL_PURE_VIRTUAL_P (dtor) = true;
+         FOR_EACH_CLONE (clone, dtor)
+           DECL_PURE_VIRTUAL_P (clone) = true;
+       }
+    }
 }
 \f
 /* Debug info for C++ classes can get very large; try to avoid
diff --git a/gcc/testsuite/g++.dg/other/abstract6.C b/gcc/testsuite/g++.dg/other/abstract6.C
new file mode 100644 (file)
index 0000000..ceba1a6
--- /dev/null
@@ -0,0 +1,10 @@
+// PR c++/60532
+
+class A
+{
+  ~A ();
+};
+class B : A
+{
+  virtual void m () = 0;
+};