Commit f576dfc4 by Jason Merrill Committed by Jason Merrill

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
parent e308bc5a
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> 2003-01-12 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (get_arglist_len_in_bytes): Remove. * cp-tree.h (get_arglist_len_in_bytes): Remove.
......
...@@ -2536,8 +2536,11 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) ...@@ -2536,8 +2536,11 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
cand = candidates; /* any one will do */ cand = candidates; /* any one will do */
cand->second_conv = build1 (AMBIG_CONV, totype, expr); cand->second_conv = build1 (AMBIG_CONV, totype, expr);
ICS_USER_FLAG (cand->second_conv) = 1; ICS_USER_FLAG (cand->second_conv) = 1;
/* Don't set ICS_BAD_FLAG; an ambiguous conversion is no worse than if (!any_strictly_viable (candidates))
another user-defined conversion. */ 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; return cand;
} }
......
...@@ -291,13 +291,15 @@ build_base_path (code, expr, binfo, nonnull) ...@@ -291,13 +291,15 @@ build_base_path (code, expr, binfo, nonnull)
return error_mark_node; 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); fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull);
if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr)) if (fixed_type_p <= 0 && TREE_SIDE_EFFECTS (expr))
expr = save_expr (expr); expr = save_expr (expr);
if (!want_pointer) if (want_pointer && !nonnull)
expr = build_unary_op (ADDR_EXPR, expr, 0);
else if (!nonnull)
null_test = build (EQ_EXPR, boolean_type_node, expr, integer_zero_node); null_test = build (EQ_EXPR, boolean_type_node, expr, integer_zero_node);
offset = BINFO_OFFSET (binfo); offset = BINFO_OFFSET (binfo);
...@@ -1833,7 +1835,7 @@ maybe_warn_about_overly_private_class (t) ...@@ -1833,7 +1835,7 @@ maybe_warn_about_overly_private_class (t)
return; return;
has_nonprivate_method = 1; has_nonprivate_method = 1;
break; /* Keep searching for a static member function. */
} }
else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn)) else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn))
has_member_fn = 1; has_member_fn = 1;
...@@ -1980,7 +1982,7 @@ resort_field_decl_cmp (x_p, y_p) ...@@ -1980,7 +1982,7 @@ resort_field_decl_cmp (x_p, y_p)
void void
resort_sorted_fields (obj, orig_obj, new_value, cookie) resort_sorted_fields (obj, orig_obj, new_value, cookie)
void *obj; void *obj;
void *orig_obj; void *orig_obj ATTRIBUTE_UNUSED;
gt_pointer_operator new_value; gt_pointer_operator new_value;
void *cookie; void *cookie;
{ {
...@@ -2042,7 +2044,7 @@ resort_method_name_cmp (m1_p, m2_p) ...@@ -2042,7 +2044,7 @@ resort_method_name_cmp (m1_p, m2_p)
void void
resort_type_method_vec (obj, orig_obj, new_value, cookie) resort_type_method_vec (obj, orig_obj, new_value, cookie)
void *obj; void *obj;
void *orig_obj; void *orig_obj ATTRIBUTE_UNUSED;
gt_pointer_operator new_value; gt_pointer_operator new_value;
void *cookie; void *cookie;
{ {
......
...@@ -1904,33 +1904,14 @@ build_class_member_access_expr (tree object, tree member, ...@@ -1904,33 +1904,14 @@ build_class_member_access_expr (tree object, tree member,
return error_mark_node; return error_mark_node;
} }
/* Transform `(a, b).x' into `(*(a, &b)).x' and `(a ? b : c).x' into /* Transform `(a, b).x' into `(*(a, &b)).x', `(a ? b : c).x' into
`(*(a ? &b : &c)).x'. Unfortunately, expand_expr cannot handle a `(*(a ? &b : &c)).x', and so on. A COND_EXPR is only an lvalue
COMPONENT_REF where the first operand is a conditional or comma in the frontend; only _DECLs and _REFs are lvalues in the backend. */
expression with class type. */ {
if (TREE_CODE (object) == COMPOUND_EXPR) tree temp = unary_complex_lvalue (ADDR_EXPR, object);
{ if (temp)
object = build (COMPOUND_EXPR, object = build_indirect_ref (temp, NULL);
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);
}
/* In [expr.ref], there is an explicit list of the valid choices for /* In [expr.ref], there is an explicit list of the valid choices for
MEMBER. We check for each of those cases here. */ MEMBER. We check for each of those cases here. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment