From 8634c649cb1ea6d85a53f1fab3bd28af869b934f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 25 Apr 2005 00:06:37 +0200 Subject: [PATCH] re PR middle-end/20991 (ICE in cgraph_mark_reachable_node) 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. From-SVN: r98674 --- gcc/ChangeLog | 8 ++++++++ gcc/cgraph.h | 4 ++++ gcc/cp/ChangeLog | 7 +++++++ gcc/cp/Make-lang.in | 3 ++- gcc/cp/class.c | 3 +++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/opt/pr20991.C | 34 ++++++++++++++++++++++++++++++++++ gcc/varasm.c | 12 +++++++++--- 8 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr20991.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2b72034..b392d66 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 02fa662..fc0fa78 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 a0ebc89..07f7daa 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 00075b3..eeb4129 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 6423fbc..5052aaa 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 7937386..f58b43c 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 0000000..32b3d05 --- /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 86d386e..bab9437 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) { -- 2.7.4