From: jakub Date: Sun, 24 Apr 2005 22:06:37 +0000 (+0000) Subject: PR middle-end/20991 X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=880afb804d8c8dd903dacb8c3e1383a80eba225c 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. * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2b72034591b..b392d668df3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2005-04-24 Jakub Jelinek + + 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 * tree-ssa-copy.c (copy_prop_visit_cond_stmt): Use diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 02fa662061f..fc0fa7858e5 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a0ebc891a55..07f7daa5f5b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2005-04-24 Jakub Jelinek + + 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 * mangle.c (write_builtin_type): Handle integer types which are diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 00075b30a9f..eeb41290892 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -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) diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6423fbcf894..5052aaaf6b0 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 79373868287..f58b43c1ac7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2005-04-24 Jakub Jelinek + 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 index 00000000000..32b3d05c351 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr20991.C @@ -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 (); +} diff --git a/gcc/varasm.c b/gcc/varasm.c index 86d386e0ff8..bab9437ec0a 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -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) {