aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c73
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;