diff options
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r-- | gcc/cp/call.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index b8d72f4f348..3020b9c6543 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -660,8 +660,7 @@ standard_conversion (tree to, tree from, tree expr) else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE && TREE_CODE (TREE_TYPE (to)) == VECTOR_TYPE && TREE_CODE (TREE_TYPE (from)) == VECTOR_TYPE - && ((*targetm.vector_opaque_p) (TREE_TYPE (to)) - || (*targetm.vector_opaque_p) (TREE_TYPE (from)))) + && vector_types_compatible_p (TREE_TYPE (to), TREE_TYPE (from))) conv = build_conv (ck_std, to, conv); else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE) || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE)) @@ -820,8 +819,7 @@ standard_conversion (tree to, tree from, tree expr) conv->rank = cr_promotion; } else if (fcode == VECTOR_TYPE && tcode == VECTOR_TYPE - && ((*targetm.vector_opaque_p) (from) - || (*targetm.vector_opaque_p) (to))) + && vector_types_compatible_p (from, to)) return build_conv (ck_std, to, conv); else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) && is_properly_derived_from (from, to)) @@ -3363,7 +3361,7 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) We need to force the lvalue-to-rvalue conversion here for class types, so we get TARGET_EXPRs; trying to deal with a COND_EXPR of class rvalues that isn't wrapped with a TARGET_EXPR plays havoc with exception - regions. */ + regions. */ arg2 = force_rvalue (arg2); if (!CLASS_TYPE_P (arg2_type)) @@ -4061,6 +4059,36 @@ enforce_access (tree basetype_path, tree decl) return true; } +/* APPLE LOCAL begin direct-binding-refs turly 20020224 */ + +/* Should we *really* call a constructor for the object whose reference type + we want? If we have a user conversion function which returns the ref + type directly, there's no need to call the object's constructor as we + can bind directly (dcl.init.ref.) + + These must be exactly the same types. */ + +static int really_call_constructor_p (tree, tree, tree); +static int +really_call_constructor_p (tree expr, tree convfn, tree totype) +{ + /* TEMPORARILY DISABLING THIS "FIX" NOW WE HAVE A SOURCE WORKAROUND. */ + /* However, we'll leave the code here pending input from the FSF + on this issue. */ + + if (0 /* && ! NEED_TEMPORARY_P (convfn) Watch out! this macro is undefined */ + && TREE_CODE (expr) == INDIRECT_REF + && TREE_CODE (TREE_TYPE (convfn)) == METHOD_TYPE + && TREE_CODE (TREE_TYPE (TREE_TYPE (convfn))) == REFERENCE_TYPE + && TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_TYPE (convfn)))) == RECORD_TYPE + && TREE_TYPE (TREE_TYPE (TREE_TYPE (convfn))) == totype + && TREE_TYPE (expr) == totype) + return 0; + + return 1; +} +/* APPLE LOCAL end direct-binding-refs turly 20020224 */ + /* Initialize a temporary of type TYPE with EXPR. The FLAGS are a bitwise or of LOOKUP_* values. If any errors are warnings are generated, set *DIAGNOSTIC_FN to "error" or "warning", @@ -4172,6 +4200,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, If the target is a class, that means call a ctor. */ if (IS_AGGR_TYPE (totype) + /* APPLE LOCAL direct-binding-refs turly 20020224 */ + && really_call_constructor_p (expr, convfn, totype) && (inner >= 0 || !lvalue_p (expr))) { expr = (build_temp @@ -4812,7 +4842,11 @@ build_over_call (struct z_candidate *cand, int flags) mark_used (fn); - if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0) + /* APPLE LOCAL begin -findirect-virtual-calls 2001-10-30 sts */ + if (DECL_VINDEX (fn) + && (flag_indirect_virtual_calls + || (flags & LOOKUP_NONVIRTUAL) == 0)) + /* APPLE LOCAL end -findirect-virtual-calls 2001-10-30 sts */ { tree t, *p = &TREE_VALUE (converted_args); tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)), @@ -4826,6 +4860,33 @@ build_over_call (struct z_candidate *cand, int flags) t = build_pointer_type (TREE_TYPE (fn)); if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn))) fn = build_java_interface_fn_ref (fn, *p); + /* APPLE LOCAL begin -findirect-virtual-calls 2001-10-30 sts */ + /* If this is not really supposed to be a virtual call, find the + vtable corresponding to the correct type, and use it. */ + else if (flags & LOOKUP_NONVIRTUAL) { + tree call_site_type = TREE_TYPE (cand->access_path); + tree fn_class_type = DECL_CLASS_CONTEXT (fn); + + my_friendly_assert (call_site_type != NULL && + fn_class_type != NULL && + AGGREGATE_TYPE_P (call_site_type) && + AGGREGATE_TYPE_P (fn_class_type), + 20020717); + my_friendly_assert(lookup_base(TYPE_MAIN_VARIANT (call_site_type), + TYPE_MAIN_VARIANT (fn_class_type), + ba_any | ba_quiet, + NULL) != NULL, + 20020719); + + if (TYPE_USES_MULTIPLE_INHERITANCE (call_site_type) + || TYPE_USES_VIRTUAL_BASECLASSES (call_site_type)) + error ("indirect virtual calls are invalid for a type that uses multiple or virtual inheritance"); + + fn = (build_vfn_ref_using_vtable + (BINFO_VTABLE (TYPE_BINFO (call_site_type)), + DECL_VINDEX (fn))); + } + /* APPLE LOCAL end -findirect-virtual-calls 2001-10-30 sts */ else fn = build_vfn_ref (build_indirect_ref (*p, 0), DECL_VINDEX (fn)); TREE_TYPE (fn) = t; |