diff options
author | Jason Merrill <jason@redhat.com> | 2014-02-28 19:17:09 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2014-02-28 19:17:09 -0500 |
commit | 570215f99d7ea33be820a1c5512ff885d7ca9f36 (patch) | |
tree | d1938735e3056002352e997933aca0c2bd44d7cb /gcc | |
parent | e73cafdee12fc5658d556990aa0add6c98b9ab2b (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ipa-devirt.c | 17 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ipa/devirt-28.C | 17 |
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" } } |