OSDN Git Service

PR middle-end/20991
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 24 Apr 2005 22:06:37 +0000 (22:06 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 24 Apr 2005 22:06:37 +0000 (22:06 +0000)
* cgraph.h (cgraph_local_info): Add vtable_method field.
* varasm.c (mark_decl_referenced): If cgraph_global_info_ready
and node is vtable_method, finalized and not reachable, don't do
anything.

* class.c: Include cgraph.h.
(cp_fold_obj_type_ref): Set node->local.vtable_method.
* Make-lang.in (cgraph.o): Depend on $(CGRAPH_H).

* g++.dg/opt/pr20991.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98674 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cgraph.h
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/class.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr20991.C [new file with mode: 0644]
gcc/varasm.c

index 2b72034..b392d66 100644 (file)
@@ -1,3 +1,11 @@
+2005-04-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/20991
+       * cgraph.h (cgraph_local_info): Add vtable_method field.
+       * varasm.c (mark_decl_referenced): If cgraph_global_info_ready
+       and node is vtable_method, finalized and not reachable, don't do
+       anything.
+
 2005-04-24  Kazu Hirata  <kazu@cs.umass.edu>
 
        * tree-ssa-copy.c (copy_prop_visit_cond_stmt): Use
index 02fa662..fc0fa78 100644 (file)
@@ -51,6 +51,10 @@ struct cgraph_local_info GTY(())
   /* True if statics_read_for_function and
      statics_written_for_function contain valid data.  */
   bool for_functions_valid;
+
+  /* True if the function is going to be emitted in some other translation
+     unit, referenced from vtable.  */
+  bool vtable_method;
 };
 
 /* Information about the function that needs to be computed globally
index a0ebc89..07f7daa 100644 (file)
@@ -1,3 +1,10 @@
+2005-04-24  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/20991
+       * class.c: Include cgraph.h.
+       (cp_fold_obj_type_ref): Set node->local.vtable_method.
+       * Make-lang.in (cgraph.o): Depend on $(CGRAPH_H).
+
 2005-04-12  Markus F.X.J. Oberhumer  <markus@oberhumer.com>
 
        * mangle.c (write_builtin_type): Handle integer types which are
index 00075b3..eeb4129 100644 (file)
@@ -243,7 +243,8 @@ cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_
    diagnostic.h gt-cp-typeck2.h
 cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
    diagnostic.h convert.h c-common.h
-cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(TARGET_H) convert.h
+cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(TARGET_H) \
+   convert.h $(CGRAPH_H)
 cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \
      diagnostic.h intl.h gt-cp-call.h convert.h target.h
 cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
index 6423fbc..5052aaa 100644 (file)
@@ -35,6 +35,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "target.h"
 #include "convert.h"
+#include "cgraph.h"
 
 /* The number of nested classes being processed.  If we are not in the
    scope of any class, this is zero.  */
@@ -7719,6 +7720,8 @@ cp_fold_obj_type_ref (tree ref, tree known_type)
                                  DECL_VINDEX (fndecl)));
 #endif
 
+  cgraph_node (fndecl)->local.vtable_method = true;
+
   return build_address (fndecl);
 }
 
index 7937386..f58b43c 100644 (file)
@@ -1,5 +1,8 @@
 2005-04-24  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/20991
+       * g++.dg/opt/pr20991.C: New test.
+
        * gcc.dg/compat/struct-layout-1_generate.c: In arrays avoid types
        where sizeof (type) < __alignof__ (type).
        * gcc.dg/compat/struct-layout-1.h: Likewise.
diff --git a/gcc/testsuite/g++.dg/opt/pr20991.C b/gcc/testsuite/g++.dg/opt/pr20991.C
new file mode 100644 (file)
index 0000000..32b3d05
--- /dev/null
@@ -0,0 +1,34 @@
+// PR middle-end/20991
+// { dg-options "-O2" }
+// { dg-do compile }
+
+struct S
+{
+  virtual inline int foo () const;
+  virtual inline bool bar () const;
+  virtual int baz (int) const;
+};
+
+inline int S::foo () const
+{
+  return 1;
+}
+
+inline bool S::bar () const
+{
+  return foo () == 0;
+}
+
+void A ()
+{
+  S s;
+  if (s.bar ())
+    s.foo ();
+}
+
+void B ()
+{
+  S s;
+  if (s.bar ())
+    s.foo ();
+}
index 86d386e..bab9437 100644 (file)
@@ -1955,9 +1955,15 @@ mark_decl_referenced (tree decl)
 {
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
-      /* Extern inline functions don't become needed when referenced.  */
-      if (!DECL_EXTERNAL (decl))
-        cgraph_mark_needed_node (cgraph_node (decl));
+      /* Extern inline functions don't become needed when referenced.
+        If we know a method will be emitted in other TU and no new
+        functions can be marked reachable, just use the external
+        definition.  */
+      struct cgraph_node *node = cgraph_node (decl);
+      if (!DECL_EXTERNAL (decl)
+         && (!node->local.vtable_method || !cgraph_global_info_ready
+             || !node->local.finalized))
+       cgraph_mark_needed_node (node);
     }
   else if (TREE_CODE (decl) == VAR_DECL)
     {