From f576dfc407d1c68d514c2be8c8505c33b00ccee6 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 13 Jan 2003 04:14:47 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 13 +++++++++++++ gcc/cp/call.c | 7 +++++-- gcc/cp/class.c | 14 ++++++++------ gcc/cp/typeck.c | 35 ++++++++--------------------------- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4111b95f114..b209ca4c0ea 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2003-01-13 Jason Merrill + + 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 * cp-tree.h (get_arglist_len_in_bytes): Remove. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index cd93f7bbe4b..5340356d4d5 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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; } diff --git a/gcc/cp/class.c b/gcc/cp/class.c index bace3f4d7c9..6d492f962f8 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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; { diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index e7921c55e10..2c896d4ef20 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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. */ -- 2.30.2