re PR c++/8748 (ICE in cp_expr_size at cp/cp-lang.c: 307)
PR c++/8748 * class.c (build_base_path): Take the address before calling save_expr. * call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if all the ambiguous conversions are bad. * class.c (maybe_warn_about_overly_private_class): Don't stop searching when we find a nonprivate method. * typeck.c (build_class_member_access_expr): Use unary_complex_lvalue. From-SVN: r61246
This commit is contained in:
parent
e308bc5ad3
commit
f576dfc407
|
@ -1,3 +1,16 @@
|
|||
2003-01-13 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/8748
|
||||
* class.c (build_base_path): Take the address before calling save_expr.
|
||||
|
||||
* call.c (build_user_type_conversion_1): Do set ICS_BAD_FLAG if
|
||||
all the ambiguous conversions are bad.
|
||||
|
||||
* class.c (maybe_warn_about_overly_private_class): Don't stop
|
||||
searching when we find a nonprivate method.
|
||||
|
||||
* typeck.c (build_class_member_access_expr): Use unary_complex_lvalue.
|
||||
|
||||
2003-01-12 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (get_arglist_len_in_bytes): Remove.
|
||||
|
|
|
@ -2536,8 +2536,11 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
|
|||
cand = candidates; /* any one will do */
|
||||
cand->second_conv = build1 (AMBIG_CONV, totype, expr);
|
||||
ICS_USER_FLAG (cand->second_conv) = 1;
|
||||
/* Don't set ICS_BAD_FLAG; an ambiguous conversion is no worse than
|
||||
another user-defined conversion. */
|
||||
if (!any_strictly_viable (candidates))
|
||||
ICS_BAD_FLAG (cand->second_conv) = 1;
|
||||
/* If there are viable candidates, don't set ICS_BAD_FLAG; an
|
||||
ambiguous conversion is no worse than another user-defined
|
||||
conversion. */
|
||||
|
||||
return cand;
|
||||
}
|
||||
|
|
|
@ -291,13 +291,15 @@ build_base_path (code, expr, binfo, nonnull)
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (!want_pointer)
|
||||
/* This must happen before the call to save_expr. */
|
||||
expr = build_unary_op (ADDR_EXPR, expr, 0);
|
||||
|
||||
fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
|
||||
if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr))
|
||||
expr = save_expr (expr);
|
||||
|
||||
if (!want_pointer)
|
||||
expr = build_unary_op (ADDR_EXPR, expr, 0);
|
||||
else if (!nonnull)
|
||||
if (want_pointer && !nonnull)
|
||||
null_test = build (EQ_EXPR, boolean_type_node, expr, integer_zero_node);
|
||||
|
||||
offset = BINFO_OFFSET (binfo);
|
||||
|
@ -1833,7 +1835,7 @@ maybe_warn_about_overly_private_class (t)
|
|||
return;
|
||||
|
||||
has_nonprivate_method = 1;
|
||||
break;
|
||||
/* Keep searching for a static member function. */
|
||||
}
|
||||
else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
|
||||
has_member_fn = 1;
|
||||
|
@ -1980,7 +1982,7 @@ resort_field_decl_cmp (x_p, y_p)
|
|||
void
|
||||
resort_sorted_fields (obj, orig_obj, new_value, cookie)
|
||||
void *obj;
|
||||
void *orig_obj;
|
||||
void *orig_obj ATTRIBUTE_UNUSED;
|
||||
gt_pointer_operator new_value;
|
||||
void *cookie;
|
||||
{
|
||||
|
@ -2042,7 +2044,7 @@ resort_method_name_cmp (m1_p, m2_p)
|
|||
void
|
||||
resort_type_method_vec (obj, orig_obj, new_value, cookie)
|
||||
void *obj;
|
||||
void *orig_obj;
|
||||
void *orig_obj ATTRIBUTE_UNUSED;
|
||||
gt_pointer_operator new_value;
|
||||
void *cookie;
|
||||
{
|
||||
|
|
|
@ -1904,33 +1904,14 @@ build_class_member_access_expr (tree object, tree member,
|
|||
return error_mark_node;
|
||||
}
|
||||
|
||||
/* Transform `(a, b).x' into `(*(a, &b)).x' and `(a ? b : c).x' into
|
||||
`(*(a ? &b : &c)).x'. Unfortunately, expand_expr cannot handle a
|
||||
COMPONENT_REF where the first operand is a conditional or comma
|
||||
expression with class type. */
|
||||
if (TREE_CODE (object) == COMPOUND_EXPR)
|
||||
{
|
||||
object = build (COMPOUND_EXPR,
|
||||
build_pointer_type (object_type),
|
||||
TREE_OPERAND (object, 0),
|
||||
build_unary_op (ADDR_EXPR,
|
||||
TREE_OPERAND (object, 1),
|
||||
/*noconvert=*/1));
|
||||
object = build_indirect_ref (object, NULL);
|
||||
}
|
||||
else if (TREE_CODE (object) == COND_EXPR)
|
||||
{
|
||||
object = build (COND_EXPR,
|
||||
build_pointer_type (object_type),
|
||||
TREE_OPERAND (object, 0),
|
||||
build_unary_op (ADDR_EXPR,
|
||||
TREE_OPERAND (object, 1),
|
||||
/*noconvert=*/1),
|
||||
build_unary_op (ADDR_EXPR,
|
||||
TREE_OPERAND (object, 2),
|
||||
/*noconvert=*/1));
|
||||
object = build_indirect_ref (object, NULL);
|
||||
}
|
||||
/* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
|
||||
`(*(a ? &b : &c)).x', and so on. A COND_EXPR is only an lvalue
|
||||
in the frontend; only _DECLs and _REFs are lvalues in the backend. */
|
||||
{
|
||||
tree temp = unary_complex_lvalue (ADDR_EXPR, object);
|
||||
if (temp)
|
||||
object = build_indirect_ref (temp, NULL);
|
||||
}
|
||||
|
||||
/* In [expr.ref], there is an explicit list of the valid choices for
|
||||
MEMBER. We check for each of those cases here. */
|
||||
|
|
Loading…
Reference in New Issue