gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Check that function is still...
authorJan Hubicka <jh@suse.cz>
Tue, 6 Jul 2010 11:44:34 +0000 (13:44 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 6 Jul 2010 11:44:34 +0000 (11:44 +0000)
* gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Check that
function is still available to fold into.

From-SVN: r161866

gcc/ChangeLog
gcc/gimple-fold.c

index 156b55a0c855efa3a5b0a59d2c8a41d272b254be..59455aac58a09b1f41c58f369cb970f68f142b72 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-05  Jan Hubicka  <jh@suse.cz>
+
+       * gimple-fold.c (gimple_fold_obj_type_ref_known_binfo): Check that
+       function is still available to fold into.
+
 2010-07-05  Nathan Froyd  <froydnj@codesourcery.com>
 
        * vec.h (FOR_EACH_VEC_ELT_REVERSE): New macro.
index 6af651140006574818fca407c5e87bf5dff2a9e9..659102b988bd5d6a521b4dd29c86b3223798ef7f 100644 (file)
@@ -1156,7 +1156,7 @@ gimple_fold_builtin (gimple stmt)
               fold_convert (TREE_TYPE (gimple_call_lhs (stmt)), val[0]);
 
          /* If the result is not a valid gimple value, or not a cast
-            of a valid gimple value, then we can not use the result.  */
+            of a valid gimple value, then we cannot use the result.  */
          if (is_gimple_val (new_val)
              || (is_gimple_cast (new_val)
                  && is_gimple_val (TREE_OPERAND (new_val, 0))))
@@ -1351,6 +1351,7 @@ gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo)
 {
   HOST_WIDE_INT i;
   tree v, fndecl;
+  struct cgraph_node *node;
 
   v = BINFO_VIRTUALS (known_binfo);
   i = 0;
@@ -1362,6 +1363,14 @@ gimple_fold_obj_type_ref_known_binfo (HOST_WIDE_INT token, tree known_binfo)
     }
 
   fndecl = TREE_VALUE (v);
+  node = cgraph_get_node (fndecl);
+  /* When cgraph node is missing and function is not public, we cannot
+     devirtualize.  This can happen in WHOPR when the actual method
+     ends up in other partition, because we found devirtualization
+     possibility too late.  */
+  if ((!node || !node->analyzed)
+      && (!TREE_PUBLIC (fndecl) || DECL_COMDAT (fndecl)))
+    return NULL;
   return build_fold_addr_expr (fndecl);
 }