re PR c++/58678 (pykde4-4.11.2 link error (devirtualization too trigger happy))
authorJason Merrill <jason@redhat.com>
Sat, 1 Mar 2014 00:17:09 +0000 (19:17 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 1 Mar 2014 00:17:09 +0000 (19:17 -0500)
PR c++/58678
* ipa-devirt.c (ipa_devirt): Don't choose an implicitly-declared
function.

From-SVN: r208241

gcc/ChangeLog
gcc/ipa-devirt.c
gcc/testsuite/g++.dg/ipa/devirt-28.C [new file with mode: 0644]

index 87e4bb3..56da660 100644 (file)
@@ -1,3 +1,9 @@
+2014-02-28  Jason Merrill  <jason@redhat.com>
+
+       PR c++/58678
+       * ipa-devirt.c (ipa_devirt): Don't choose an implicitly-declared
+       function.
+
 2014-02-28  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/60314
index 21649cb..2f84f17 100644 (file)
@@ -1710,7 +1710,7 @@ ipa_devirt (void)
 
   int npolymorphic = 0, nspeculated = 0, nconverted = 0, ncold = 0;
   int nmultiple = 0, noverwritable = 0, ndevirtualized = 0, nnotdefined = 0;
-  int nwrong = 0, nok = 0, nexternal = 0;;
+  int nwrong = 0, nok = 0, nexternal = 0, nartificial = 0;
 
   FOR_EACH_DEFINED_FUNCTION (n)
     {  
@@ -1820,6 +1820,17 @@ ipa_devirt (void)
                nexternal++;
                continue;
              }
+           /* Don't use an implicitly-declared destructor (c++/58678).  */
+           struct cgraph_node *non_thunk_target
+             = cgraph_function_node (likely_target);
+           if (DECL_ARTIFICIAL (non_thunk_target->decl)
+               && DECL_COMDAT (non_thunk_target->decl))
+             {
+               if (dump_file)
+                 fprintf (dump_file, "Target is artificial\n\n");
+               nartificial++;
+               continue;
+             }
            if (cgraph_function_body_availability (likely_target)
                <= AVAIL_OVERWRITABLE
                && symtab_can_be_discarded (likely_target))
@@ -1862,10 +1873,10 @@ ipa_devirt (void)
             " %i speculatively devirtualized, %i cold\n"
             "%i have multiple targets, %i overwritable,"
             " %i already speculated (%i agree, %i disagree),"
-            " %i external, %i not defined\n",
+            " %i external, %i not defined, %i artificial\n",
             npolymorphic, ndevirtualized, nconverted, ncold,
             nmultiple, noverwritable, nspeculated, nok, nwrong,
-            nexternal, nnotdefined);
+            nexternal, nnotdefined, nartificial);
   return ndevirtualized ? TODO_remove_functions : 0;
 }
 
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-28.C b/gcc/testsuite/g++.dg/ipa/devirt-28.C
new file mode 100644 (file)
index 0000000..e18b818
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/58678
+// { dg-options "-O3 -fdump-ipa-devirt" }
+
+struct A {
+  virtual ~A();
+};
+struct B : A {
+  virtual int m_fn1();
+};
+void fn1(B* b) {
+  delete b;
+}
+
+// { dg-final { scan-assembler-not "_ZN1AD2Ev" } }
+// { dg-final { scan-assembler-not "_ZN1BD0Ev" } }
+// { dg-final { scan-ipa-dump "Target is artificial" "devirt" } }
+// { dg-final { cleanup-ipa-dump "devirt" } }