From 570215f99d7ea33be820a1c5512ff885d7ca9f36 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 28 Feb 2014 19:17:09 -0500 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++++ gcc/ipa-devirt.c | 17 ++++++++++++++--- gcc/testsuite/g++.dg/ipa/devirt-28.C | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ipa/devirt-28.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 87e4bb3e8848..56da66051d2d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-02-28 Jason Merrill + + PR c++/58678 + * ipa-devirt.c (ipa_devirt): Don't choose an implicitly-declared + function. + 2014-02-28 Paolo Carlini PR c++/60314 diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 21649cb214cc..2f84f177d192 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 000000000000..e18b8189716f --- /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" } } -- 2.47.2