re PR c++/60566 (r208573 omits needed thunks)
authorJason Merrill <jason@redhat.com>
Wed, 26 Mar 2014 16:50:26 +0000 (12:50 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 26 Mar 2014 16:50:26 +0000 (12:50 -0400)
PR c++/60566
PR c++/58678
* class.c (build_vtbl_initializer): Handle abstract dtors here.
* search.c (get_pure_virtuals): Not here.

From-SVN: r208845

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/search.c
gcc/ipa-devirt.c
gcc/testsuite/g++.dg/abi/thunk6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ipa/devirt-21.C
gcc/testsuite/g++.dg/ipa/devirt-23.C

index 23a2c8f..518eb22 100644 (file)
@@ -1,5 +1,10 @@
 2014-03-25  Jason Merrill  <jason@redhat.com>
 
+       PR c++/60566
+       PR c++/58678
+       * class.c (build_vtbl_initializer): Handle abstract dtors here.
+       * search.c (get_pure_virtuals): Not here.
+
        PR c++/60375
        * parser.c (cp_parser_lambda_expression): Don't parse the body of
        a lambda in unevaluated context.
index b46391b..d277e07 100644 (file)
@@ -9017,6 +9017,16 @@ build_vtbl_initializer (tree binfo,
              if (!TARGET_VTABLE_USES_DESCRIPTORS)
                init = fold_convert (vfunc_ptr_type_node,
                                     build_fold_addr_expr (fn));
+             /* Don't refer to a virtual destructor from a constructor
+                vtable or a vtable for an abstract class, since destroying
+                an object under construction is undefined behavior and we
+                don't want it to be considered a candidate for speculative
+                devirtualization.  But do create the thunk for ABI
+                compliance.  */
+             if (DECL_DESTRUCTOR_P (fn_original)
+                 && (CLASSTYPE_PURE_VIRTUALS (DECL_CONTEXT (fn_original))
+                     || orig_binfo != binfo))
+               init = size_zero_node;
            }
        }
 
index d99e182..c3eed90 100644 (file)
@@ -2115,22 +2115,6 @@ 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
index 2f84f17..6fb1449 100644 (file)
@@ -1261,7 +1261,7 @@ get_polymorphic_call_info (tree fndecl,
            }
 
          /* If the function is constructor or destructor, then
-            the type is possibly in consturction, but we know
+            the type is possibly in construction, but we know
             it is not derived type.  */
          if (DECL_CXX_CONSTRUCTOR_P (fndecl)
              || DECL_CXX_DESTRUCTOR_P (fndecl))
diff --git a/gcc/testsuite/g++.dg/abi/thunk6.C b/gcc/testsuite/g++.dg/abi/thunk6.C
new file mode 100644 (file)
index 0000000..e3d07f2
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/60566
+// We need to emit the construction vtable thunk for ~C even if we aren't
+// going to use it.
+
+struct A
+{
+  virtual void f() = 0;
+  virtual ~A() {}
+};
+
+struct B: virtual A { int i; };
+struct C: virtual A { int i; ~C(); };
+
+C::~C() {}
+
+int main() {}
+
+// { dg-final { scan-assembler "_ZTv0_n32_N1CD1Ev" } }
index 99f60af..675bd08 100644 (file)
@@ -37,5 +37,5 @@ main()
 {
   class C c;
 }
-/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */
+/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" { xfail *-*-* } } } */
 /* { dg-final { cleanup-ipa-dump "cp" } } */
index a32c7d6..98d86ae 100644 (file)
@@ -45,5 +45,5 @@ main()
 {
   class C c;
 }
-/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */
+/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" { xfail *-*-* } } } */
 /* { dg-final { cleanup-ipa-dump "cp" } } */