/* Bypass access control for 'this' parameter. */
else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
{
- tree parmtype = TREE_VALUE (parm);
tree arg = build_this (first_arg != NULL_TREE
? first_arg
: (*args)[arg_index]);
tree argtype = TREE_TYPE (arg);
- tree converted_arg;
- tree base_binfo;
if (arg == error_mark_node)
return error_mark_node;
return error_mark_node;
}
+ /* The class where FN is defined. */
+ tree ctx = DECL_CONTEXT (fn);
+
/* See if the function member or the whole class type is declared
final and the call can be devirtualized. */
- if (DECL_FINAL_P (fn)
- || CLASSTYPE_FINAL (TYPE_METHOD_BASETYPE (TREE_TYPE (fn))))
+ if (DECL_FINAL_P (fn) || CLASSTYPE_FINAL (ctx))
flags |= LOOKUP_NONVIRTUAL;
- /* If we know the dynamic type of the object, look up the final overrider
- in the BINFO. */
- if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
- && resolves_to_fixed_type_p (arg))
- {
- tree binfo = cand->conversion_path;
- if (BINFO_TYPE (binfo) != DECL_CONTEXT (fn))
- binfo = lookup_base (binfo, DECL_CONTEXT (fn), ba_unique,
- NULL, complain);
- fn = lookup_vfn_in_binfo (DECL_VINDEX (fn), binfo);
- flags |= LOOKUP_NONVIRTUAL;
- }
-
/* [class.mfct.non-static]: If a non-static member function of a class
X is called for an object that is not of type X, or of a type
derived from X, the behavior is undefined.
So we can assume that anything passed as 'this' is non-null, and
optimize accordingly. */
- gcc_assert (TYPE_PTR_P (parmtype));
- /* Convert to the base in which the function was declared. */
- gcc_assert (cand->conversion_path != NULL_TREE);
- converted_arg = build_base_path (PLUS_EXPR,
- arg,
- cand->conversion_path,
- 1, complain);
/* Check that the base class is accessible. */
if (!accessible_base_p (TREE_TYPE (argtype),
BINFO_TYPE (cand->conversion_path), true))
}
/* If fn was found by a using declaration, the conversion path
will be to the derived class, not the base declaring fn. We
- must convert from derived to base. */
- base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)),
- TREE_TYPE (parmtype), ba_unique,
- NULL, complain);
- converted_arg = build_base_path (PLUS_EXPR, converted_arg,
- base_binfo, 1, complain);
+ must convert to the base. */
+ tree base_binfo = cand->conversion_path;
+ if (BINFO_TYPE (base_binfo) != ctx)
+ {
+ base_binfo = lookup_base (base_binfo, ctx, ba_unique, NULL, complain);
+ if (base_binfo == error_mark_node)
+ return error_mark_node;
+ }
+ tree converted_arg = build_base_path (PLUS_EXPR, arg,
+ base_binfo, 1, complain);
+
+ /* If we know the dynamic type of the object, look up the final overrider
+ in the BINFO. */
+ if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0
+ && resolves_to_fixed_type_p (arg))
+ {
+ fn = lookup_vfn_in_binfo (DECL_VINDEX (fn), base_binfo);
+ flags |= LOOKUP_NONVIRTUAL;
+ }
argarray[j++] = converted_arg;
parm = TREE_CHAIN (parm);