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; }

Reply via email to