Commit f8b0f44f by Easwaran Raman Committed by Jason Merrill

re PR c++/59031 (vtable lookup not optimized away)

	PR c++/59031
	* call.c (build_new_method_call_1): Comnpare function context
	with BASELINK_BINFO type rather than instance type before
	marking the call with LOOKUP_NONVIRTUAL.

From-SVN: r205317
parent 18768fae
2013-11-23 Easwaran Raman <eraman@google.com>
PR c++/59031
* call.c (build_new_method_call_1): Comnpare function context
with BASELINK_BINFO type rather than instance type before
marking the call with LOOKUP_NONVIRTUAL.
2013-11-23 Jason Merrill <jason@redhat.com> 2013-11-23 Jason Merrill <jason@redhat.com>
PR c++/58868 PR c++/58868
......
...@@ -7514,7 +7514,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, ...@@ -7514,7 +7514,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
struct z_candidate *candidates = 0, *cand; struct z_candidate *candidates = 0, *cand;
tree explicit_targs = NULL_TREE; tree explicit_targs = NULL_TREE;
tree basetype = NULL_TREE; tree basetype = NULL_TREE;
tree access_binfo; tree access_binfo, binfo;
tree optype; tree optype;
tree first_mem_arg = NULL_TREE; tree first_mem_arg = NULL_TREE;
tree name; tree name;
...@@ -7553,6 +7553,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, ...@@ -7553,6 +7553,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (!conversion_path) if (!conversion_path)
conversion_path = BASELINK_BINFO (fns); conversion_path = BASELINK_BINFO (fns);
access_binfo = BASELINK_ACCESS_BINFO (fns); access_binfo = BASELINK_ACCESS_BINFO (fns);
binfo = BASELINK_BINFO (fns);
optype = BASELINK_OPTYPE (fns); optype = BASELINK_OPTYPE (fns);
fns = BASELINK_FUNCTIONS (fns); fns = BASELINK_FUNCTIONS (fns);
if (TREE_CODE (fns) == TEMPLATE_ID_EXPR) if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
...@@ -7799,13 +7800,13 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args, ...@@ -7799,13 +7800,13 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
{ {
/* Optimize away vtable lookup if we know that this /* Optimize away vtable lookup if we know that this
function can't be overridden. We need to check if function can't be overridden. We need to check if
the context and the instance type are the same, the context and the type where we found fn are the same,
actually FN might be defined in a different class actually FN might be defined in a different class
type because of a using-declaration. In this case, we type because of a using-declaration. In this case, we
do not want to perform a non-virtual call. */ do not want to perform a non-virtual call. */
if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL) if (DECL_VINDEX (fn) && ! (flags & LOOKUP_NONVIRTUAL)
&& same_type_ignoring_top_level_qualifiers_p && same_type_ignoring_top_level_qualifiers_p
(DECL_CONTEXT (fn), TREE_TYPE (instance)) (DECL_CONTEXT (fn), BINFO_TYPE (binfo))
&& resolves_to_fixed_type_p (instance, 0)) && resolves_to_fixed_type_p (instance, 0))
flags |= LOOKUP_NONVIRTUAL; flags |= LOOKUP_NONVIRTUAL;
if (explicit_targs) if (explicit_targs)
......
...@@ -359,7 +359,8 @@ struct GTY(()) tree_overload { ...@@ -359,7 +359,8 @@ struct GTY(()) tree_overload {
/* Returns true iff NODE is a BASELINK. */ /* Returns true iff NODE is a BASELINK. */
#define BASELINK_P(NODE) \ #define BASELINK_P(NODE) \
(TREE_CODE (NODE) == BASELINK) (TREE_CODE (NODE) == BASELINK)
/* The BINFO indicating the base from which the BASELINK_FUNCTIONS came. */ /* The BINFO indicating the base in which lookup found the
BASELINK_FUNCTIONS. */
#define BASELINK_BINFO(NODE) \ #define BASELINK_BINFO(NODE) \
(((struct tree_baselink*) BASELINK_CHECK (NODE))->binfo) (((struct tree_baselink*) BASELINK_CHECK (NODE))->binfo)
/* The functions referred to by the BASELINK; either a FUNCTION_DECL, /* The functions referred to by the BASELINK; either a FUNCTION_DECL,
......
// PR c++/59031
// { dg-do compile }
// { dg-options "-fdump-tree-gimple " }
class B {
public:
virtual int add (int a, int b) {return a+ b;}
};
class D : public B {
};
int foo (int a, int b) {
D d;
return d.add(a, b);
}
// { dg-final { scan-tree-dump-not "OBJ_TYPE_REF" "gimple" } }
// { dg-final { cleanup-tree-dump "gimple" } }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment