Hi, this patch fixes more of PR64043: when we have OBJ_TYPE_REF without a BINFO, we should not try to devirtualize. This is most conveniently done by modifying virtual_method_call_p. I still need to figure out why -O0 / -O2 combination with LTO leads to -fdevirtualize being set. It should not.
Bootstrapped/regtested x86_64-linux, comitted. Honza Index: ChangeLog =================================================================== --- ChangeLog (revision 218726) +++ ChangeLog (working copy) @@ -1,5 +1,11 @@ 2014-12-14 Jan HUbicka <hubi...@ucw.cz> + PR lto/64043 + * tree.c (virtual_method_call_p): Return false when OTR type has + no BINFO. + +2014-12-14 Jan HUbicka <hubi...@ucw.cz> + * cgraphunit.c (analyze_functions): Do not analyze extern inline funtions when not optimizing; skip comdat locals. Index: testsuite/ChangeLog =================================================================== --- testsuite/ChangeLog (revision 218701) +++ testsuite/ChangeLog (working copy) @@ -1,3 +1,8 @@ +2014-12-14 Jan HUbicka <hubi...@ucw.cz> + + PR lto/64043 + * g++.dg/lto/pr64043_0.C: New testcase. + 2014-12-13 Tobias Burnus <bur...@net-b.de> * gfortran.dg/realloc_on_assign_21.f90: Update dg-error. Index: tree.c =================================================================== --- tree.c (revision 218701) +++ tree.c (working copy) @@ -11864,12 +11864,17 @@ virtual_method_call_p (tree target) { if (TREE_CODE (target) != OBJ_TYPE_REF) return false; - target = TREE_TYPE (target); - gcc_checking_assert (TREE_CODE (target) == POINTER_TYPE); - target = TREE_TYPE (target); - if (TREE_CODE (target) == FUNCTION_TYPE) + tree t = TREE_TYPE (target); + gcc_checking_assert (TREE_CODE (t) == POINTER_TYPE); + t = TREE_TYPE (t); + if (TREE_CODE (t) == FUNCTION_TYPE) + return false; + gcc_checking_assert (TREE_CODE (t) == METHOD_TYPE); + /* If we do not have BINFO associated, it means that type was built + without devirtualization enabled. Do not consider this a virtual + call. */ + if (!TYPE_BINFO (obj_type_ref_class (target))) return false; - gcc_checking_assert (TREE_CODE (target) == METHOD_TYPE); return true; } Index: testsuite/g++.dg/lto/pr64043_0.C =================================================================== --- testsuite/g++.dg/lto/pr64043_0.C (revision 0) +++ testsuite/g++.dg/lto/pr64043_0.C (revision 0) @@ -0,0 +1,14 @@ +// { dg-lto-do link } +// { dg-lto-options { { -flto -std=c++11 } } } +// { dg-extra-ld-options "-r -nostdlib -O2" } +class Validator +{ +public: + virtual ~Validator (); +}; +class FooWriter +{ + Validator *validator; + ~FooWriter (); +}; +FooWriter::~FooWriter () { delete validator; }