+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
/* 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
+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
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)
#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. */
DECL_VINDEX (fndecl)));
#endif
+ cgraph_node (fndecl)->local.vtable_method = true;
+
return build_address (fndecl);
}
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.
--- /dev/null
+// 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 ();
+}
{
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)
{