aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-02-28 19:17:09 -0500
committerJason Merrill <jason@gcc.gnu.org>2014-02-28 19:17:09 -0500
commit570215f99d7ea33be820a1c5512ff885d7ca9f36 (patch)
treed1938735e3056002352e997933aca0c2bd44d7cb
parente73cafdee12fc5658d556990aa0add6c98b9ab2b (diff)
downloadgcc-570215f99d7ea33be820a1c5512ff885d7ca9f36.zip
gcc-570215f99d7ea33be820a1c5512ff885d7ca9f36.tar.gz
gcc-570215f99d7ea33be820a1c5512ff885d7ca9f36.tar.bz2
re PR c++/58678 (pykde4-4.11.2 link error (devirtualization too trigger happy))
PR c++/58678 * ipa-devirt.c (ipa_devirt): Don't choose an implicitly-declared function. From-SVN: r208241
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/ipa-devirt.c17
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-28.C17
3 files changed, 37 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 87e4bb3..56da660 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 21649cb..2f84f17 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -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
index 0000000..e18b818
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-28.C
@@ -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" } }