On 09/08/2014 03:51 PM, Jan Hubicka wrote:
You did not attach the patch.
Oops.
commit e57303b73d20fa75ffc535bbc219dc0f6472e431 Author: Jason Merrill <ja...@redhat.com> Date: Mon Sep 8 13:11:58 2014 -0400 PR c++/61214 PR c++/62224 gcc/ * gimple-fold.c (can_refer_decl_in_current_unit_p): Don't allow reference to a DECL_EXTERNAL COMDAT. gcc/cp/ * decl2.c (decl_needed_p): Revert virtual functions change. diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 944b5ee..5549075 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1940,11 +1940,6 @@ decl_needed_p (tree decl) if (flag_keep_inline_dllexport && lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))) return true; - /* Virtual functions might be needed for devirtualization. */ - if (flag_devirtualize - && TREE_CODE (decl) == FUNCTION_DECL - && DECL_VIRTUAL_P (decl)) - return true; /* Otherwise, DECL does not need to be emitted -- yet. A subsequent reference to DECL might cause it to be emitted later. */ return false; diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index c6aea65..2527d29 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -146,7 +146,8 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl) The second is important when devirtualization happens during final compilation stage when making a new reference no longer makes callee to be compiled. */ - if (!node || !node->definition || node->global.inlined_to) + if (!node || !node->definition + || DECL_EXTERNAL (decl) || node->global.inlined_to) { gcc_checking_assert (!TREE_ASM_WRITTEN (decl)); return false; diff --git a/gcc/testsuite/g++.dg/ipa/devirt-39.C b/gcc/testsuite/g++.dg/ipa/devirt-39.C index fbeea12..8cd734d 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-39.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-39.C @@ -1,5 +1,5 @@ // PR c++/61214 -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-options "-O2" } */ struct Base { @@ -24,5 +24,4 @@ int main() return 0; } -/* { dg-final { scan-tree-dump-not "OBJ_TYPE_REF" "optimized" } } */ -/* { dg-final { cleanup-tree-dump "optimized" } } */ +/* { dg-final { scan-assembler-not "_ZN3Foo5cloneEv" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-40.C b/gcc/testsuite/g++.dg/ipa/devirt-40.C new file mode 100644 index 0000000..9c3bdf5 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/devirt-40.C @@ -0,0 +1,21 @@ +// PR c++/62224 +// { dg-options "-O2" } +// For 4.9, we don't want to devirtualize f and thus create a reference to g. + +struct A +{ + virtual void f () = 0; +}; + +class B : A +{ + virtual void f () { g(); } + void g(); +}; + +void h (A *a) +{ + a->f (); +} + +// { dg-final { scan-assembler-not "_ZN1B1gEv" } }