diff options
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r-- | gcc/cp/call.c | 89 |
1 files changed, 71 insertions, 18 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 4655430a2bd..a97abdce906 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -538,8 +538,7 @@ build_conv (conversion_kind code, tree type, conversion *from) } /* Build a representation of the identity conversion from EXPR to - itself. The TYPE should match the the type of EXPR, if EXPR is - non-NULL. */ + itself. The TYPE should match the type of EXPR, if EXPR is non-NULL. */ static conversion * build_identity_conv (tree type, tree expr) @@ -743,6 +742,13 @@ standard_conversion (tree to, tree from, tree expr, int flags) else if (expr && string_conv_p (to, expr, 0)) /* converting from string constant to char *. */ conv = build_conv (ck_qual, to, conv); + /* APPLE LOCAL begin 4154928 */ + /* Allow conversions among arbitrary ObjC pointer types (base + conversions have been already handled above). */ + else if (c_dialect_objc () + && objc_compare_types (to, from, -3, NULL_TREE)) + conv = build_conv (ck_ptr, to, conv); + /* APPLE LOCAL end 4154928 */ else if (ptr_reasonably_similar (to_pointee, from_pointee)) { conv = build_conv (ck_ptr, to, conv); @@ -2450,7 +2456,7 @@ print_z_candidates (struct z_candidate *candidates) /* USER_SEQ is a user-defined conversion sequence, beginning with a USER_CONV. STD_SEQ is the standard conversion sequence applied to the result of the conversion function to convert it to the final - desired type. Merge the the two sequences into a single sequence, + desired type. Merge the two sequences into a single sequence, and return the merged sequence. */ static conversion * @@ -3751,20 +3757,6 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, if (overloaded_p) *overloaded_p = true; - if (warn_synth - && fnname == ansi_assopname (NOP_EXPR) - && DECL_ARTIFICIAL (cand->fn) - && candidates->next - && ! candidates->next->next) - { - warning ("using synthesized %q#D for copy assignment", - cand->fn); - cp_warning_at (" where cfront would use %q#D", - cand == candidates - ? candidates->next->fn - : candidates->fn); - } - result = build_over_call (cand, LOOKUP_NORMAL); } else @@ -4079,6 +4071,36 @@ enforce_access (tree basetype_path, tree decl) return true; } +/* APPLE LOCAL begin direct-binding-refs 20020224 --turly */ + +/* 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 20020224 --turly */ + /* Check that a callable constructor to initialize a temporary of TYPE from an EXPR exists. */ @@ -4246,6 +4268,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 20020224 --turly */ + && really_call_constructor_p (expr, convfn, totype) && (inner >= 0 || !lvalue_p (expr))) { expr = (build_temp @@ -4904,7 +4928,11 @@ build_over_call (struct z_candidate *cand, int flags) mark_used (fn); - if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0) + /* APPLE LOCAL begin KEXT indirect-virtual-calls --sts */ + if (DECL_VINDEX (fn) + && (flag_apple_kext + || (flags & LOOKUP_NONVIRTUAL) == 0)) + /* APPLE LOCAL end KEXT indirect-virtual-calls --sts */ { tree t, *p = &TREE_VALUE (converted_args); tree binfo = lookup_base (TREE_TYPE (TREE_TYPE (*p)), @@ -4918,6 +4946,31 @@ 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 KEXT indirect-virtual-calls --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); + + gcc_assert (call_site_type != NULL && + fn_class_type != NULL && + AGGREGATE_TYPE_P (call_site_type) && + AGGREGATE_TYPE_P (fn_class_type)); + gcc_assert (lookup_base(TYPE_MAIN_VARIANT (call_site_type), + TYPE_MAIN_VARIANT (fn_class_type), + ba_any | ba_quiet, + NULL) != NULL); + + if (BINFO_N_BASE_BINFOS (TYPE_BINFO (call_site_type)) > 1 + || CLASSTYPE_VBASECLASSES (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 KEXT indirect-virtual-calls --sts */ else fn = build_vfn_ref (*p, DECL_VINDEX (fn)); TREE_TYPE (fn) = t; |